Esempio n. 1
0
Texture TextureFactory::loadTexture(const std::string& fileName, ObjectsCache& cache,
	bool async, TextureLoaderDelegate* delegate)
{
	if (fileName.length() == 0)
		return Texture();
	
	CriticalSectionScope lock(_csTextureLoading);
	
	std::string file = application().environment().resolveScalableFileName(fileName,
		renderContext()->screenScaleFactor());
	
	if (!fileExists(file))
	{
		log::error("Unable to find texture file: %s", file.c_str());
		return Texture();
	}
	
	uint64_t cachedFileProperty = 0;
    Texture texture = cache.findAnyObject(file, &cachedFileProperty);
	if (texture.invalid())
	{
		TextureDescription::Pointer desc =
			async ? et::loadTextureDescription(file, false) : et::loadTexture(file);

		if (desc.valid())
		{
			bool calledFromAnotherThread = Threading::currentThread() != threading().renderingThread();
			
			texture = Texture(new TextureData(renderContext(), desc, desc->origin(), async || calledFromAnotherThread));
			cache.manage(texture, ObjectLoader::Pointer(this));
			
			if (async)
				_loadingThread->addRequest(desc->origin(), texture, delegate);
			else if (calledFromAnotherThread)
				assert(false && "ERROR: Unable to load texture synchronously from non-rendering thread.");
		}
		
	}
	else
	{
		auto newProperty = cache.getFileProperty(file);
		if (cachedFileProperty != newProperty)
			reloadObject(texture, cache);
	
		if (async && (delegate != nullptr))
		{
			Invocation1 i;
			i.setTarget(delegate, &TextureLoaderDelegate::textureDidStartLoading, texture);
			i.invokeInMainRunLoop();
			i.setTarget(delegate, &TextureLoaderDelegate::textureDidLoad, texture);
			i.invokeInMainRunLoop();
		}
	}
   
	return texture;
}
Esempio n. 2
0
Program::Pointer ProgramFactory::loadProgram(const std::string& file, ObjectsCache& cache,
	const StringList& defines)
{
	auto cachedPrograms = cache.findObjects(file);
	for (Program::Pointer cached : cachedPrograms)
	{
		if (cached.valid())
		{
			if (cached->defines().size() == defines.size())
			{
				bool same = true;
				for (auto& inDefine : defines)
				{
					for (auto& cDefine : cached->defines())
					{
						if (inDefine != cDefine)
						{
							same = false;
							break;
						}
						
						if (!same)
							break;
					}
				}
				if (same)
					return cached;
			}
		}
	}
	
	std::string vertex_shader;
	std::string geom_shader;
	std::string frag_shader;

	StringList sourceFiles = loadProgramSources(file, vertex_shader, geom_shader, frag_shader);
	
	if (sourceFiles.empty())
		return Program::Pointer::create(renderContext());
	
	std::string workFolder = getFilePath(file);
	
	parseSourceCode(ShaderType_Vertex, vertex_shader, defines, workFolder);
	parseSourceCode(ShaderType_Geometry, geom_shader, defines, workFolder);
	parseSourceCode(ShaderType_Fragment, frag_shader, defines, workFolder);
	
	Program::Pointer program = Program::Pointer::create(renderContext(), vertex_shader, geom_shader,
		frag_shader, getFileName(file), file, defines);
	
	for (auto& s : sourceFiles)
		program->addOrigin(s);
	
	cache.manage(program, _private->loader);
	return program;
}
Esempio n. 3
0
Texture::Pointer TextureFactory::loadTexture(const std::string& fileName, ObjectsCache& cache,
	bool async, TextureLoaderDelegate* delegate)
{
	if (fileName.length() == 0)
		return Texture::Pointer();
	
	CriticalSectionScope lock(_csTextureLoading);
	
	auto file = resolveTextureName(fileName);
	if (!fileExists(file))
		return Texture::Pointer();
	
	uint64_t cachedFileProperty = 0;
    Texture::Pointer texture = cache.findAnyObject(file, &cachedFileProperty);
	if (texture.invalid())
	{
		TextureDescription::Pointer desc =
			async ? et::loadTextureDescription(file, false) : et::loadTexture(file);
		
		int maxTextureSize = static_cast<int>(RenderingCapabilities::instance().maxTextureSize());
		if ((desc->size.x > maxTextureSize) || (desc->size.y > maxTextureSize))
		{
			log::warning("Attempt to load texture with dimensions (%d x %d) larger than max allowed (%d)",
				desc->size.x, desc->size.y, maxTextureSize);
		}
		
		if (desc.valid())
		{
			bool calledFromAnotherThread = !threading::inMainThread();
			
			texture = Texture::Pointer::create(renderContext(), desc, desc->origin(), async || calledFromAnotherThread);
			cache.manage(texture, _private->loader);
			
			if (async)
			{
				_loadingThread->addRequest(desc->origin(), texture, delegate);
			}
			else if (calledFromAnotherThread)
			{
				ET_FAIL("ERROR: Unable to load texture synchronously from non-rendering thread.");
			}
		}
		
	}
	else
	{
		auto newProperty = cache.getFileProperty(file);
		if (cachedFileProperty != newProperty)
			reloadObject(texture, cache);
	
		if (async)
		{
			textureDidStartLoading.invokeInMainRunLoop(texture);
			if (delegate != nullptr)
			{
				Invocation1 i;
				i.setTarget(delegate, &TextureLoaderDelegate::textureDidStartLoading, texture);
				i.invokeInMainRunLoop();
			}
			
			textureDidLoad.invokeInMainRunLoop(texture);
			if (delegate != nullptr)
			{
				Invocation1 i;
				i.setTarget(delegate, &TextureLoaderDelegate::textureDidLoad, texture);
				i.invokeInMainRunLoop();
			}
		}

	}
   
	return texture;
}
Esempio n. 4
0
Texture::Pointer TextureFactory::loadTexturesToCubemap(const std::string& posx, const std::string& negx,
	const std::string& posy, const std::string& negy, const std::string& posz, const std::string& negz,
	ObjectsCache& cache)
{
	TextureDescription::Pointer layers[6] = 
	{
		et::loadTexture(application().resolveFileName(posx)),
		et::loadTexture(application().resolveFileName(negx)),
		et::loadTexture(application().resolveFileName(negy)),
		et::loadTexture(application().resolveFileName(posy)),
		et::loadTexture(application().resolveFileName(posz)),
		et::loadTexture(application().resolveFileName(negz))
	};

	int maxCubemapSize = static_cast<int>(RenderingCapabilities::instance().maxCubemapTextureSize());
	
	for (size_t l = 0; l < 6; ++l)
	{
		if (layers[l].valid())
		{
			if ((layers[l]->size.x > maxCubemapSize) || (layers[l]->size.y > maxCubemapSize))
			{
				log::error("Cubemap %s size of (%d x %d) is larger than allowed %dx%d",
					layers[l]->origin().c_str(), layers[l]->size.x, layers[l]->size.y, maxCubemapSize, maxCubemapSize);
				return Texture::Pointer();
			}
		}
		else
		{
			log::error("Unable to load cubemap face.");
			return Texture::Pointer();
		}
	}

	std::string texId = layers[0]->origin() + ";";
	for (size_t l = 1; l < 6; ++l)
	{
		texId += (l < 5) ? layers[l]->origin() + ";" : layers[l]->origin();
		if ((layers[l-1]->size != layers[l]->size) || 
			(layers[l-1]->format != layers[l]->format) ||
			(layers[l-1]->internalformat != layers[l]->internalformat) || 
			(layers[l-1]->type != layers[l]->type) || 
			(layers[l-1]->mipMapCount != layers[l]->mipMapCount) || 
			(layers[l-1]->compressed != layers[l]->compressed) ||
			(layers[l-1]->data.size() != layers[l]->data.size()))
		{
			log::error("Failed to load cubemap textures. Textures `%s` and `%s` aren't identical",
				layers[l-1]->origin().c_str(), layers[l]->origin().c_str());
			return Texture::Pointer();
		}
	}

	size_t layerSize = layers[0]->dataSizeForAllMipLevels();
	TextureDescription::Pointer desc = TextureDescription::Pointer::create();
	desc->target = TextureTarget::Texture_Cube;
	desc->layersCount = 6;
	desc->bitsPerPixel = layers[0]->bitsPerPixel;
	desc->channels = layers[0]->channels;
	desc->compressed = layers[0]->compressed;
	desc->format = layers[0]->format;
	desc->internalformat = layers[0]->internalformat;
	desc->mipMapCount= layers[0]->mipMapCount;
	desc->size = layers[0]->size;
	desc->type = layers[0]->type;
	desc->data.resize(desc->layersCount * layerSize);
	
	for (size_t l = 0; l < desc->layersCount; ++l)
		etCopyMemory(desc->data.element_ptr(l * layerSize), layers[l]->data.element_ptr(0), layerSize);

	Texture::Pointer result = Texture::Pointer::create(renderContext(), desc, texId, false);
	
	for (size_t i = 0; i < 6; ++i)
		result->addOrigin(layers[i]->origin());
	
	cache.manage(result, _private->loader);
	
	return result;
}