void AllTextures::Parse_Script(std::ostream &os){ { std::map<std::string,TextureMap*>*all_maps=maps.get_map(); typename std::map<std::string,TextureMap*>::iterator it = all_maps->begin(); TextureMap* map; while (it != all_maps->end()) { map=it->second; map->Save_script(folder_path+map->path); os<<"TextureMap:"<<std::endl; os<<" ScriptPath:"<<std::endl; os<<" "+map->path<<std::endl; it++; } } { std::map<std::string,MapTree<TextureMap, Texture>* >*all_dirs=dirs.get_map(); typename std::map<std::string,MapTree<TextureMap, Texture>* >::iterator it=all_dirs->begin(); AllTextures* dir; while (it != all_dirs->end()) { dir=dynamic_cast<AllTextures*>(it->second); dir->Save_script(folder_path+dir->path); os<<"TextureDir:"<<std::endl; os<<" ScriptPath:"<<std::endl; os<<" "+dir->path<<std::endl; it++; } } }
void State::initializeZeroTextures(const TextureMap &zeroTextures) { for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++) { TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first]; for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit) { samplerTextureArray[textureUnit].set(i->second.get()); } } }
TextureMap & getTextureMap() { static TextureMap map; static bool registeredShutdown = false; if (!registeredShutdown) { Platform::addShutdownHook([&]{ map.clear(); }); registeredShutdown = true; } return map; }
Tree::Tree(const std::string& name, double initialLength, double initialThickness, int initialBranches, int leavesPerBranch, int leafStartLevel, double thicknessReduction, double lengthReduction, int recursiveDepth, int seed) : SceneNode(name) { totalBranches = 0; totalLeaves = 0; ::initialLength = initialLength; ::initialThickness = initialThickness; ::initialBranches = initialBranches; ::leavesPerBranch = leavesPerBranch; ::leafStartLevel = leafStartLevel; ::thicknessReduction = thicknessReduction; ::lengthReduction = lengthReduction; ::recursiveDepth = recursiveDepth; wood.bump("woodbump.png"); srand( seed ); Branch* trunk = new Branch("Trunk", 0, initialThickness, initialLength); trunk->rotate('x', -90); add_child(trunk); //std::cerr << "Total Branches: " << totalBranches // << " Total Leaves: " << totalLeaves << std::endl; }
void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) { // Textures have a detach method on State rather than a simple // removeBinding, because the zero/null texture objects are managed // separately, and don't have to go through the Context's maps or // the ResourceManager. // [OpenGL ES 2.0.24] section 3.8 page 84: // If a texture object is deleted, it is as if all texture units which are bound to that texture object are // rebound to texture object zero for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) { GLenum textureType = bindingVec->first; TextureBindingVector &textureVector = bindingVec->second; for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) { BindingPointer<Texture> &binding = textureVector[textureIdx]; if (binding.id() == texture) { auto it = zeroTextures.find(textureType); ASSERT(it != zeroTextures.end()); // Zero textures are the "default" textures instead of NULL binding.set(it->second.get()); } } } // [OpenGL ES 2.0.24] section 4.4 page 112: // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this // image was attached in the currently bound framebuffer. if (mReadFramebuffer) { mReadFramebuffer->detachTexture(texture); } if (mDrawFramebuffer) { mDrawFramebuffer->detachTexture(texture); } }
/** Evict textures in order to reduce texture memory usage. Textures * will be evicted until the total size of textures managed by this * texture loader is less than or equal to desired memory. Least recently * used textures are evicted first. No texture with a last used value * greater than mostRecentAllowed will be evicted, even if it means that * the desired memory target can't be reached. * * Evict textures must be called from a thread in which a GL context * is current (typically the display thread.) It can take some time to * process all textures, so it shouldn't be called frequently (i.e. * once a frame is too often.) * * \return the total size of all textures remaining */ v_uint64 TextureMapLoader::evictTextures(v_uint64 desiredMemory, v_int64 mostRecentAllowed) { #if DEBUG_EVICTION // Show all textures managed by this loader for (TextureTable::const_iterator iter = m_textures.begin(); iter != m_textures.end(); ++iter) { VESTA_LOG("Texture: %s, mem: %.2f", iter->second.ptr()->name().c_str(), double(iter->second.ptr()->memoryUsage()) / (1024*1024)); } #endif v_uint64 textureMemory = textureMemoryUsed(); // Early out if the memory usage target is already met if (textureMemory < desiredMemory) { return textureMemory; } // Create a list of textures sorted such that least recently used textures are first. vector<TextureMap*> sortedTextures; for (TextureTable::const_iterator iter = m_textures.begin(); iter != m_textures.end(); ++iter) { sortedTextures.push_back(iter->second.ptr()); } sort(sortedTextures.begin(), sortedTextures.end(), TextureAgePredicate()); // Evict textures until we reach the memory target for (vector<TextureMap*>::const_iterator iter = sortedTextures.begin(); iter != sortedTextures.end() && (*iter)->lastUsed() <= mostRecentAllowed && textureMemory > desiredMemory; ++iter) { TextureMap* t = *iter; if (t->isResident()) { #if DEBUG_EVICTION VESTA_LOG("evict %s @ %d", t->name().c_str(), (int) t->lastUsed()); #endif textureMemory -= t->memoryUsage(); t->evict(); } } return textureMemory; }
Scene::Scene(const std::string &fileName,uint width, uint height ,const int aType ) { accelType = aType; extMeshCache = new ExtMeshCache(); texMapCache = new TextureMapCache(); SDL_LOG("Reading scene: " << fileName); scnProp = new Properties(fileName); //-------------------------------------------------------------------------- // Read camera position and target //-------------------------------------------------------------------------- std::vector<float> vf = GetParameters(*scnProp, "scene.camera.lookat", 6, "10.0 0.0 0.0 0.0 0.0 0.0"); Point o(vf.at(0), vf.at(1), vf.at(2)); Point t(vf.at(3), vf.at(4), vf.at(5)); SDL_LOG("Camera postion: " << o); SDL_LOG("Camera target: " << t); vf = GetParameters(*scnProp, "scene.camera.up", 3, "0.0 0.0 0.1"); const Vector up(vf.at(0), vf.at(1), vf.at(2)); camera = new PerspectiveCamera(o, t, up); camera->lensRadius = scnProp->GetFloat("scene.camera.lensradius", 0.f); camera->focalDistance = scnProp->GetFloat("scene.camera.focaldistance", 10.f); camera->fieldOfView = scnProp->GetFloat("scene.camera.fieldofview", 45.f); // Check if camera motion blur is enabled if (scnProp->GetInt("scene.camera.motionblur.enable", 0)) { camera->motionBlur = true; vf = GetParameters(*scnProp, "scene.camera.motionblur.lookat", 6, "10.0 1.0 0.0 0.0 1.0 0.0"); camera->mbOrig = Point(vf.at(0), vf.at(1), vf.at(2)); camera->mbTarget = Point(vf.at(3), vf.at(4), vf.at(5)); vf = GetParameters(*scnProp, "scene.camera.motionblur.up", 3, "0.0 0.0 0.1"); camera->mbUp = Vector(vf.at(0), vf.at(1), vf.at(2)); } //-------------------------------------------------------------------------- // Read all materials //-------------------------------------------------------------------------- std::vector<std::string> matKeys = scnProp->GetAllKeys("scene.materials."); if (matKeys.size() == 0) throw std::runtime_error("No material definition found"); for (std::vector<std::string>::const_iterator matKey = matKeys.begin(); matKey != matKeys.end(); ++matKey) { const std::string &key = *matKey; const std::string matType = Properties::ExtractField(key, 2); if (matType == "") throw std::runtime_error("Syntax error in " + key); const std::string matName = Properties::ExtractField(key, 3); if (matName == "") throw std::runtime_error("Syntax error in " + key); SDL_LOG("Material definition: " << matName << " [" << matType << "]"); Material *mat = CreateMaterial(key, *scnProp); materialIndices[matName] = materials.size(); materials.push_back(mat); } //-------------------------------------------------------------------------- // Read all objects .ply file //-------------------------------------------------------------------------- std::vector<std::string> objKeys = scnProp->GetAllKeys("scene.objects."); if (objKeys.size() == 0) throw std::runtime_error("Unable to find object definitions"); double lastPrint = WallClockTime(); unsigned int objCount = 0; for (std::vector<std::string>::const_iterator objKey = objKeys.begin(); objKey != objKeys.end(); ++objKey) { const std::string &key = *objKey; // Check if it is the root of the definition of an object otherwise skip const size_t dot1 = key.find(".", std::string("scene.objects.").length()); if (dot1 == std::string::npos) continue; const size_t dot2 = key.find(".", dot1 + 1); if (dot2 != std::string::npos) continue; const std::string objName = Properties::ExtractField(key, 3); if (objName == "") throw std::runtime_error("Syntax error in " + key); // Build the object const std::vector<std::string> args = scnProp->GetStringVector(key, ""); const std::string plyFileName = args.at(0); const double now = WallClockTime(); if (now - lastPrint > 2.0) { SDL_LOG("PLY object count: " << objCount); lastPrint = now; } ++objCount; //SDL_LOG("PLY object [" << objName << "] file name: " << plyFileName); // Check if I have to calculate normal or not const bool usePlyNormals = (scnProp->GetInt(key + ".useplynormals", 0) != 0); // Check if I have to use an instance mesh or not ExtMesh *meshObject; if (scnProp->IsDefined(key + ".transformation")) { const std::vector<float> vf = GetParameters(*scnProp, key + ".transformation", 16, "1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0"); const Matrix4x4 mat( vf.at(0), vf.at(4), vf.at(8), vf.at(12), vf.at(1), vf.at(5), vf.at(9), vf.at(13), vf.at(2), vf.at(6), vf.at(10), vf.at(14), vf.at(3), vf.at(7), vf.at(11), vf.at(15)); const Transform trans(mat); meshObject = extMeshCache->GetExtMesh(plyFileName, usePlyNormals, trans); } else meshObject = extMeshCache->GetExtMesh(plyFileName, usePlyNormals); objectIndices[objName] = objects.size(); objects.push_back(meshObject); // Get the material const std::string matName = Properties::ExtractField(key, 2); if (matName == "") throw std::runtime_error("Syntax error in material name: " + matName); if (materialIndices.count(matName) < 1) throw std::runtime_error("Unknown material: " + matName); Material *mat = materials[materialIndices[matName]]; // Check if it is a light sources if (mat->IsLightSource()) { SDL_LOG("The " << objName << " object is a light sources with " << meshObject->GetTotalTriangleCount() << " triangles"); AreaLightMaterial *light = (AreaLightMaterial *)mat; objectMaterials.push_back(mat); for (unsigned int i = 0; i < meshObject->GetTotalTriangleCount(); ++i) { TriangleLight *tl = new TriangleLight(light, static_cast<unsigned int>(objects.size()) - 1, i, objects); lights.push_back(tl); } } else { SurfaceMaterial *surfMat = (SurfaceMaterial *)mat; objectMaterials.push_back(surfMat); } // [old deprecated syntax] Check if there is a texture map associated to the object if (args.size() > 1) { // Check if the object has UV coords if (!meshObject->HasUVs()) throw std::runtime_error("PLY object " + plyFileName + " is missing UV coordinates for texture mapping"); TexMapInstance *tm = texMapCache->GetTexMapInstance(args.at(1), 2.2f); objectTexMaps.push_back(tm); objectBumpMaps.push_back(NULL); objectNormalMaps.push_back(NULL); } else { // Check for if there is a texture map associated to the object with the new syntax const std::string texMap = scnProp->GetString(key + ".texmap", ""); if (texMap != "") { // Check if the object has UV coords if (!meshObject->HasUVs()) throw std::runtime_error("PLY object " + plyFileName + " is missing UV coordinates for texture mapping"); const float gamma = scnProp->GetFloat(key + ".texmap.gamma", 2.2f); TexMapInstance *tm = texMapCache->GetTexMapInstance(texMap, gamma); objectTexMaps.push_back(tm); } else objectTexMaps.push_back(NULL); /** * Check if there is an alpha map associated to the object * If there is, the map is added to a previously added texturemap. * If no texture map (diffuse map) is detected, a black texture * is created and the alpha map is added to it. --PC */ const std::string alphaMap = scnProp->GetString(key + ".alphamap", ""); if (alphaMap != "") { // Got an alpha map, retrieve the textureMap and add the alpha channel to it. const std::string texMap = scnProp->GetString(key + ".texmap", ""); const float gamma = scnProp->GetFloat(key + ".texmap.gamma", 2.2f); TextureMap *tm; if (!(tm = texMapCache->FindTextureMap(texMap, gamma))) { SDL_LOG("Alpha map " << alphaMap << " is for a materials without texture. A black texture has been created for support!"); // We have an alpha map without a diffuse texture. In this case we need to create // a texture map filled with black tm = new TextureMap(alphaMap, gamma, 1.0, 1.0, 1.0); tm->AddAlpha(alphaMap); TexMapInstance *tmi = texMapCache->AddTextureMap(alphaMap, tm); // Remove the NULL inserted above, when no texmap was found. Without doing this the whole thing will not work objectTexMaps.pop_back(); // Add the new texture to the chain objectTexMaps.push_back(tmi); } else { // Add an alpha map to the pre-existing diffuse texture tm->AddAlpha(alphaMap); } } // Check for if there is a bump map associated to the object const std::string bumpMap = scnProp->GetString(key + ".bumpmap", ""); if (bumpMap != "") { // Check if the object has UV coords if (!meshObject->HasUVs()) throw std::runtime_error("PLY object " + plyFileName + " is missing UV coordinates for bump mapping"); const float scale = scnProp->GetFloat(key + ".bumpmap.scale", 1.f); BumpMapInstance *bm = texMapCache->GetBumpMapInstance(bumpMap, scale); objectBumpMaps.push_back(bm); } else objectBumpMaps.push_back(NULL); // Check for if there is a normal map associated to the object const std::string normalMap = scnProp->GetString(key + ".normalmap", ""); if (normalMap != "") { // Check if the object has UV coords if (!meshObject->HasUVs()) throw std::runtime_error("PLY object " + plyFileName + " is missing UV coordinates for normal mapping"); NormalMapInstance *nm = texMapCache->GetNormalMapInstance(normalMap); objectNormalMaps.push_back(nm); } else objectNormalMaps.push_back(NULL); } } SDL_LOG("PLY object count: " << objCount); //-------------------------------------------------------------------------- // Check if there is an infinitelight source defined //-------------------------------------------------------------------------- const std::vector<std::string> ilParams = scnProp->GetStringVector("scene.infinitelight.file", ""); if (ilParams.size() > 0) { const float gamma = scnProp->GetFloat("scene.infinitelight.gamma", 2.2f); TexMapInstance *tex = texMapCache->GetTexMapInstance(ilParams.at(0), gamma); // Check if I have to use InfiniteLightBF method if (scnProp->GetInt("scene.infinitelight.usebruteforce", 0)) { SDL_LOG("Using brute force infinite light sampling"); infiniteLight = new InfiniteLightBF(tex); useInfiniteLightBruteForce = true; } else { if (ilParams.size() == 2) infiniteLight = new InfiniteLightPortal(tex, ilParams.at(1)); else infiniteLight = new InfiniteLightIS(tex); // Add the infinite light to the list of light sources lights.push_back(infiniteLight); useInfiniteLightBruteForce = false; } std::vector<float> vf = GetParameters(*scnProp, "scene.infinitelight.gain", 3, "1.0 1.0 1.0"); infiniteLight->SetGain(Spectrum(vf.at(0), vf.at(1), vf.at(2))); vf = GetParameters(*scnProp, "scene.infinitelight.shift", 2, "0.0 0.0"); infiniteLight->SetShift(vf.at(0), vf.at(1)); infiniteLight->Preprocess(); } else { infiniteLight = NULL; useInfiniteLightBruteForce = false; } //-------------------------------------------------------------------------- // Check if there is a SkyLight defined //-------------------------------------------------------------------------- const std::vector<std::string> silParams = scnProp->GetStringVector("scene.skylight.dir", ""); if (silParams.size() > 0) { if (infiniteLight) throw std::runtime_error("Can not define a skylight when there is already an infinitelight defined"); std::vector<float> sdir = GetParameters(*scnProp, "scene.skylight.dir", 3, "0.0 0.0 1.0"); const float turb = scnProp->GetFloat("scene.skylight.turbidity", 2.2f); std::vector<float> gain = GetParameters(*scnProp, "scene.skylight.gain", 3, "1.0 1.0 1.0"); SkyLight *sl = new SkyLight(turb, Vector(sdir.at(0), sdir.at(1), sdir.at(2))); infiniteLight = sl; sl->SetGain(Spectrum(gain.at(0), gain.at(1), gain.at(2))); sl->Init(); useInfiniteLightBruteForce = true; } //-------------------------------------------------------------------------- // Check if there is a SunLight defined //-------------------------------------------------------------------------- const std::vector<std::string> sulParams = scnProp->GetStringVector("scene.sunlight.dir", ""); if (sulParams.size() > 0) { std::vector<float> sdir = GetParameters(*scnProp, "scene.sunlight.dir", 3, "0.0 0.0 1.0"); const float turb = scnProp->GetFloat("scene.sunlight.turbidity", 2.2f); const float relSize = scnProp->GetFloat("scene.sunlight.relsize", 1.0f); std::vector<float> gain = GetParameters(*scnProp, "scene.sunlight.gain", 3, "1.0 1.0 1.0"); SunLight *sunLight = new SunLight(turb, relSize, Vector(sdir.at(0), sdir.at(1), sdir.at(2))); sunLight->SetGain(Spectrum(gain.at(0), gain.at(1), gain.at(2))); sunLight->Init(); lights.push_back(sunLight); } //-------------------------------------------------------------------------- camera->Update(width, height); }
// Do recursive ray tracing! You'll want to insert a lot of code here // (or places called from here) to handle reflection, refraction, etc etc. Vec3d RayTracer::traceRay(ray& r, int depth) { isect i; Vec3d colorC; if(scene->intersect(r, i)) { const Material& m = i.getMaterial(); colorC = m.shade(scene, r, i); if(depth <= 0) return colorC; Vec3d q = r.at(i.t); Vec3d rayDir = -1 * r.getDirection(); rayDir.normalize(); //REFLECTION Vec3d reflectionIntensity = m.kr(i); Vec3d reflectDir = 2 * (rayDir * i.N) * i.N - rayDir; reflectDir.normalize(); ray reflected(q, reflectDir, ray::REFLECTION); reflectionIntensity %= traceRay(reflected, depth - 1); colorC += reflectionIntensity; //END REFLECTION //REFRACTION Vec3d refractionIntensity = m.kt(i); double indexRatio, flip; if(refractionIntensity[0] <= 0.0 && refractionIntensity[1] <= 0.0 && refractionIntensity[2] <= 0.0) { return colorC; } if(i.N * r.getDirection() < 0.0) { indexRatio = 1.0 / m.index(i); flip = -1; } else { indexRatio = m.index(i) / 1.0; flip = 1; } //Check for TIR if(i.N * r.getDirection() > 0.0f) { double iAngle = i.N * r.getDirection(); if((1 - (indexRatio*indexRatio*(1.0f - iAngle * iAngle))) < 0.0) return colorC; } Vec3d rayNormalPart = (rayDir * i.N) * i.N; Vec3d rayTangentialPart = rayNormalPart - rayDir; Vec3d refractTangential = (indexRatio) * rayTangentialPart; double temp = refractTangential * refractTangential; if(temp > 1) temp = 0; Vec3d refractNormal = (flip * i.N) * sqrt( 1.0 - temp); Vec3d refractDir = refractNormal + refractTangential; reflectDir.normalize(); ray refracted(q, refractDir, ray::REFRACTION); refractionIntensity %= traceRay(refracted, depth - 1); colorC += refractionIntensity; //END REFRACTION } else { //do cube mapping? if(!traceUI->doCubeMap()) return Vec3d(0,0,0); TextureMap* texture; double u, v; Vec3d direction = r.getDirection(); double x = direction.n[0]; double y = direction.n[1]; double z = direction.n[2]; double max = std::abs(x); if(std::abs(y) > max) max = std::abs(y); if(std::abs(z) > max) max = std::abs(z); if(max == std::abs(x)) { if(x < 0) { texture = cubeMap->getXnegMap(); u = ((z/std::abs(x)) + 1)/2; v = ((y/std::abs(x)) + 1)/2; } else { texture = cubeMap->getXposMap(); u = ((-z/std::abs(x)) + 1)/2; v = ((y/std::abs(x)) + 1)/2; } } else if(max == std::abs(y)) { if(y < 0) { texture = cubeMap->getYnegMap(); u = ((x/std::abs(y)) + 1)/2; v = ((z/std::abs(y)) + 1)/2; } else { texture = cubeMap->getYposMap(); u = ((x/std::abs(y)) + 1)/2; v = ((-z/std::abs(y)) + 1)/2; } } else { if(z < 0) { texture = cubeMap->getZnegMap(); u = ((-x/std::abs(z)) + 1)/2; v = ((y/std::abs(z)) + 1)/2; } else { texture = cubeMap->getZposMap(); u = ((x/std::abs(z)) + 1)/2; v = ((y/std::abs(z)) + 1)/2; } } colorC = texture->getMappedValue(Vec2d(u,v)); } return colorC; }
void SlotMachine::Update(Canvas *_canvas) { Canvas *canvas = _canvas; if (state == SlotMachineState::sl_inProcess) { // Все ли барабаны остановлены bool allStoped = true; // Обновляем и проверяем состояние барабанов TypeObjectsMap::iterator wit; // Итератор для карты с барабанами // Проверяем состояние барабанов for (wit = wheelsMap.begin(); wit != wheelsMap.end(); ++wit) { if (wit->second->getState() == WheelState::_running) { wit->second->Update(); allStoped = false; } } TypeObjectsMap::iterator bit; // Итератор для карты с кнопками // Все барабаны прекратили вращение if (allStoped) { bit = buttonsMap.find(ObjectRole::_start); if (bit != buttonsMap.end()) { Object *start = bit->second; if (start->getState() == ButtonState::_enabled) { // Закончили вращение. Возвращаемся в исходное состояние и проверяем результат if (result = CalcResult()) { showResultStartTime = currentTime = std::time(nullptr); state = SlotMachineState::sl_show_result; TextureMap * textureMap = canvas->getTextureMap(); TextureMap::iterator it; resultTexture = nullptr; // Обработка результатов костыль switch (result) { case r_slash: it = textureMap->find(TextureRole::_w_slash); resultTexture = it->second; break; case r_center: it = textureMap->find(TextureRole::_w_center); resultTexture = it->second; break; case r_backslah: it = textureMap->find(TextureRole::_w_backslash); resultTexture = it->second; break; } resultTexture->ena = true; } else { state = SlotMachineState::sl_waiting; start->Update(); } } } } } else if (state == SlotMachineState::sl_show_result) { currentTime = std::time(nullptr); int elapse = currentTime - showResultStartTime; if (elapse < SHOW_RESULT_DURATION) { //resultTexture->ena = true; } else { resultTexture->ena = false; state = SlotMachineState::sl_waiting; TypeObjectsMap::iterator bit; bit = buttonsMap.find(ObjectRole::_start); bit->second->Update(); } } }