void TextureFactory::reloadObject(LoadableObject::Pointer object, ObjectsCache&)
{
	TextureDescription::Pointer newData = et::loadTexture(object->origin());
	
	if (newData.valid())
		Texture::Pointer(object)->updateData(renderContext(), newData);
}
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;
}
Exemple #3
0
void Framebuffer::resize(const vec2i& sz)
{
	if (_description.size.xy() == sz) return;
	
	forceSize(sz);
	
	bool hasColor = (_description.colorInternalformat != TextureFormat::Invalid) &&
		(_description.colorIsRenderbuffer || (_description.colorFormat != TextureFormat::Invalid));
	
	bool hasDepth = (_description.depthInternalformat != TextureFormat::Invalid) &&
		(_description.depthIsRenderbuffer || (_description.depthFormat != TextureFormat::Invalid));

	if (hasColor)
	{
		if (_description.colorIsRenderbuffer)
		{
			for (uint32_t& renderBuffer : _colorRenderBuffers)
				renderBuffer = buildColorRenderbuffer(renderBuffer);
		}
		else
		{
			for (auto rt : _renderTargets)
			{
				TextureDescription::Pointer desc = rt->description();
				desc->size = sz;
				desc->data.resize(desc->layersCount * desc->dataSizeForAllMipLevels());
				desc->data.fill(0);
				rt->updateData(_rc, desc);
				setCurrentRenderTarget(rt);
			}
		}
	}
	
	if (hasDepth)
	{
		if (_description.depthIsRenderbuffer)
		{
			createOrUpdateDepthRenderbuffer();
		}
		else if (_depthBuffer.valid())
		{
			auto desc = _depthBuffer->description();
			desc->size = sz;
			desc->data.resize(desc->layersCount * desc->dataSizeForAllMipLevels());
			desc->data.fill(0);
			_depthBuffer->updateData(_rc, desc);
			setDepthTarget(_depthBuffer);
		}
	}
	
	if (hasColor || hasDepth)
		checkStatus();
}
Texture::Pointer TextureFactory::genCubeTexture(TextureFormat internalformat, uint32_t size, TextureFormat format,
	DataType type, const std::string& aName)
{
	TextureDescription::Pointer desc = TextureDescription::Pointer::create();
	
	desc->target = TextureTarget::Texture_Cube;
	
	desc->format = format;
	desc->internalformat = internalformat;
	desc->type = type;
	
	desc->size = vec2i(size);
	
	desc->mipMapCount = 1;
	desc->layersCount = 6;
	desc->bitsPerPixel = bitsPerPixelForTextureFormat(internalformat, type);
	
	desc->data = BinaryDataStorage(desc->layersCount * desc->dataSizeForAllMipLevels(), 0);
	
	return Texture::Pointer::create(renderContext(), desc, aName, false);
}
Exemple #5
0
Texture::Texture(RenderContext* rc, const TextureDescription::Pointer& desc, const std::string& id,
	bool deferred) : APIObject(id, desc->origin()), _desc(desc), _own(true)
{
#if (ET_OPENGLES)
	if (!(isPowerOfTwo(desc->size.x) && isPowerOfTwo(desc->size.y)))
		_wrap = vector3<TextureWrap>(TextureWrap::ClampToEdge);
	
	const auto& caps = OpenGLCapabilities::instance();

	if ((_desc->internalformat == TextureFormat::R) && (caps.version() > OpenGLVersion::Version_2x))
		_desc->internalformat = TextureFormat::R8;
	
#endif
	
	if (deferred)
	{
		buildProperies();
	}
	else
	{
		generateTexture(rc);
		build(rc);
	}
}
Exemple #6
0
int main(int argc, char* argv[])
{
	log::addOutput(log::ConsoleOutput::Pointer::create());
	
	bool hasPattern = false;
	bool hasRoot = false;
	bool hasOutput = false;
	bool addSpace = true;

	std::string rootFolder;
	std::string outFile;
	std::string pattern = "texture_%d.png";
	int outputSize = 1024;

	for (int i = 1; i < argc; ++i)
	{
		if ((strcmp(argv[i], "-root") == 0) && (i + 1 < argc))
		{
			rootFolder = addTrailingSlash(std::string(argv[i+1]));
			if (folderExists(rootFolder))
			{
				hasRoot = true;
				++i;
			}
			else
			{
				log::error("Root folder not found: %s", rootFolder.c_str());
				return 0;
			}
		}
		else if ((strcmp(argv[i], "-out") == 0) && (i + 1 < argc))
		{
			outFile = std::string(argv[i+1]);
			hasOutput = true;
			++i;
		}
		else if ((strcmp(argv[i], "-pattern") == 0) && (i + 1 < argc))
		{
			pattern = std::string(argv[i+1]);
			hasPattern = true;
			++i;
		}
		else if (strcmp(argv[i], "-nospace") == 0)
		{
			addSpace = false;
		}
		else if ((strcmp(argv[i], "-size") == 0) && (i + 1 < argc))
		{
			outputSize = strToInt(std::string(argv[i+1]));
			++i;
		}
	}

	if (!hasRoot || !hasOutput)
	{
		printHelp();
		return 0;
	}
		
	StringList fileList;
	TextureDescription::List textureDescriptors;
	findFiles(rootFolder, "*.png", true, fileList);	

	for (auto i : fileList)
	{
		TextureDescription::Pointer desc = TextureDescription::Pointer::create();
		png::loadInfoFromFile(i, desc.reference());
		
		if ((desc->size.x > outputSize) || (desc->size.y > outputSize))
		{
			log::error("Image %s is larger (%d x %d) than ouput size (%d x %d), use -size option",
				i.c_str(), desc->size.x, desc->size.y, outputSize, outputSize);
			return 0;
		}
		textureDescriptors.push_back(desc);
	}
	
	std::sort(textureDescriptors.begin(), textureDescriptors.end(), [](const TextureDescription::Pointer& d1,
		const TextureDescription::Pointer& d2) { return d1->size.square() > d2->size.square(); });

	TextureAtlasWriter placer(addSpace);
	while (textureDescriptors.size())
	{
		TextureAtlasWriter::TextureAtlasItem& texture = placer.addItem(vec2i(outputSize));
		TextureDescription::List::iterator i = textureDescriptors.begin();

		int placedItems = 0;
		
		while (i != textureDescriptors.end())
		{
			if (placer.placeImage(*i, texture))
			{
				++placedItems;
				i = textureDescriptors.erase(i);
			}
			else 
			{
				++i;
			}
		}
		
		texture.texture->size.x = static_cast<int>(roundToHighestPowerOfTwo(texture.maxWidth));
		texture.texture->size.y = static_cast<int>(roundToHighestPowerOfTwo(texture.maxHeight));
	}
	
	for (const auto i : placer.items())
	{
		log::info("Texture: %d x %d", i.texture->size.x, i.texture->size.y);
		
		for (const auto& ii : i.images)
		{
			log::info("(% 5d, % 5d) | (% 5d % 5d) | %s", static_cast<int>(ii.place.origin.x),
				static_cast<int>(ii.place.origin.y), static_cast<int>(ii.place.size.x),
				static_cast<int>(ii.place.size.y), getFileName(ii.image->origin()).c_str());
		}
	}

	placer.writeToFile(outFile, pattern.c_str());

	return 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;
}
Texture::Pointer TextureFactory::genTexture(TextureDescription::Pointer desc)
{
	return Texture::Pointer::create(renderContext(), desc, desc->origin(), false);
}
Texture TextureFactory::genTexture(TextureDescription::Pointer desc)
{
	return Texture(new TextureData(renderContext(), desc, desc->origin(), false));
}