// Constructor AtomRenderableManager::AtomRenderableManager() : lod(0), sphere(0), specularShader(0), validBuffers(false) { // Initialise level of detail setLOD(); // Log renderableManager qDebug() << "Ambrosia: rendering atoms using basic OpenGL"; // Populate renderFormats renderFormats = new unsigned int[3]; renderFormats[0] = SPACEFILL = Ambrosia::getToken("Render Format", "Spacefill"); renderFormats[1] = BALLSANDSTICKS = Ambrosia::getToken("Render Format", "Balls and Sticks"); renderFormats[2] = 0; // Populate renderOptions renderOptions = new unsigned int[1]; renderOptions[0] = 0; // Shader stuff if (Shader::capability() == Shader::GLSL) { specularShader = new ShaderProgram(); specularShader->addShader(loadShader((Utopia::resource_path() + "ambrosia/glsl/specular.vert").toUtf8().constData(), Shader::VERTEX)); specularShader->addShader(loadShader((Utopia::resource_path() + "ambrosia/glsl/specular.frag").toUtf8().constData(), Shader::FRAGMENT)); } }
//----------------------------------------------------------------------------- // calcLOD() //----------------------------------------------------------------------------- void LLViewerJointAttachment::calcLOD() { F32 maxarea = 0; for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin(); iter != mAttachedObjects.end(); ++iter) { if (LLViewerObject *attached_object = (*iter)) { maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale()); LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; F32 area = childp->getMaxScale() * childp->getMidScale(); maxarea = llmax(maxarea, area); } } } maxarea = llclamp(maxarea, .01f*.01f, 1.f); F32 avatar_area = (4.f * 4.f); // pixels for an avatar sized attachment F32 min_pixel_area = avatar_area / maxarea; setLOD(min_pixel_area); }
void GamePlanet::cameraPositionChanged(IngameCamera* camera) { Ogre::Vector3 camPos = camera->GetPosition(); Ogre::Vector3 planetPos = node->getPosition(); double dist = camPos.distance(planetPos) - radius; if(dist < 0) { dist = 0; } double pixelSize = camera->mPerspectiveScallingFactor * (2 * radius) / dist; PlanetLOD lodLevel; if (pixelSize <= 1) { //LOD_Invisible is used when the planet is extremely far away, and would normally be smaller than one pixel unloadLOD(LOD_Sprite); unloadLOD(LOD_Simple); unloadLOD(LOD_Complex); lodLevel = LOD_Invisible; loadLOD(LOD_Invisible); } else { if(pixelSize <= 10) { //LOD_Sprite is for long distances, where only a few pixels are rendered for the planet //At this LOD, all other LOD levels should be unloaded because the most likely won't be needed soon. unloadLOD(LOD_Simple); unloadLOD(LOD_Complex); lodLevel = LOD_Sprite; loadLOD(LOD_Sprite); // if (fullyLoadedPlanet == &planet) fullyLoadedPlanet = NULL; } else { if (pixelSize <= 750) { //LOD_Simple is for medium-ranged planets, needing moderate orbital-perspective detail, but not surface detail. lodLevel = LOD_Simple; //Load not only LOD_Simple, but also ensure LOD_Sprite is loaded loadLOD(LOD_Sprite); loadLOD(LOD_Simple); } else { if (pixelSize > 750) { //LOD_Complex is the highest level of detail, which loads everything on the planet for surface view. //If this LOD has not been loaded yet, the planet should use LOD_Medium until it is. lodLevel = LOD_Complex; //Ensure LOD_Simple and LOD_Sprite are loaded - until LOD_Complex can load, it will fall back on these loadLOD(LOD_Sprite); loadLOD(LOD_Simple); loadLOD(LOD_Complex); } } } } /* while (lodLevel < LOD_Invisible && !isloadedLOD(lodLevel)) { lodLevel = (GamePlanet::PlanetLOD)(((uint32)lodLevel) + 1); } */ setLOD(lodLevel); }
void LODmodel::draw() { setLOD(); drawLOD(*actualLOD); }