Example #1
0
//==============================================================================
Error ShaderLoader::parseFileIncludes(ResourceFilename filename, U32 depth)
{
	// first check the depth
	if(depth > MAX_INCLUDE_DEPTH)
	{
		ANKI_LOGE("The include depth is too high. "
				  "Probably circular includance");
		return ErrorCode::USER_DATA;
	}

	// load file in lines
	StringAuto txt(m_alloc);
	StringListAuto lines(m_alloc);

	ResourceFilePtr file;
	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
	ANKI_CHECK(file->readAllText(TempResourceAllocator<char>(m_alloc), txt));
	lines.splitString(txt.toCString(), '\n');
	if(lines.getSize() < 1)
	{
		ANKI_LOGE("File is empty: %s", &filename[0]);
		return ErrorCode::USER_DATA;
	}

	for(const String& line : lines)
	{
		static const CString token = "#include \"";

		if(line.find(token) == 0)
		{
			// - Expect something between the quotes
			// - Expect the last char to be a quote
			if(line.getLength() >= token.getLength() + 2
				&& line[line.getLength() - 1] == '\"')
			{
				StringAuto filen(m_alloc);
				filen.create(line.begin() + token.getLength(), line.end() - 1);

				ANKI_CHECK(parseFileIncludes(filen.toCString(), depth + 1));
			}
			else
			{
				ANKI_LOGE("Malformed #include: %s", &line[0]);
				return ErrorCode::USER_DATA;
			}
		}
		else
		{
			m_sourceLines.pushBackSprintf(m_alloc, "%s", &line[0]);
		}
	}

	return ErrorCode::NONE;
}
Error TextureAtlasResource::load(const ResourceFilename& filename, Bool async)
{
	XmlDocument doc;
	ANKI_CHECK(openFileParseXml(filename, doc));

	XmlElement rootel, el;

	//
	// <textureAtlas>
	//
	ANKI_CHECK(doc.getChildElement("textureAtlas", rootel));

	//
	// <texture>
	//
	ANKI_CHECK(rootel.getChildElement("texture", el));
	CString texFname;
	ANKI_CHECK(el.getText(texFname));
	ANKI_CHECK(getManager().loadResource<TextureResource>(texFname, m_tex, async));

	m_size[0] = m_tex->getWidth();
	m_size[1] = m_tex->getHeight();

	//
	// <subTextureMargin>
	//
	ANKI_CHECK(rootel.getChildElement("subTextureMargin", el));
	I64 margin = 0;
	ANKI_CHECK(el.getNumber(margin));
	if(margin >= I(m_tex->getWidth()) || margin >= I(m_tex->getHeight()) || margin < 0)
	{
		ANKI_RESOURCE_LOGE("Too big margin %d", U(margin));
		return Error::USER_DATA;
	}
	m_margin = margin;

	//
	// <subTextures>
	//

	// Get counts
	PtrSize namesSize = 0;
	PtrSize subTexesCount = 0;
	XmlElement subTexesEl, subTexEl;
	ANKI_CHECK(rootel.getChildElement("subTextures", subTexesEl));
	ANKI_CHECK(subTexesEl.getChildElement("subTexture", subTexEl));
	do
	{
		ANKI_CHECK(subTexEl.getChildElement("name", el));
		CString name;
		ANKI_CHECK(el.getText(name));

		if(name.getLength() < 1)
		{
			ANKI_RESOURCE_LOGE("Something wrong with the <name> tag. Probably empty");
			return Error::USER_DATA;
		}

		namesSize += name.getLength() + 1;
		++subTexesCount;

		ANKI_CHECK(subTexEl.getNextSiblingElement("subTexture", subTexEl));
	} while(subTexEl);

	// Allocate
	m_subTexNames.create(getAllocator(), namesSize);
	m_subTexes.create(getAllocator(), subTexesCount);

	// Iterate again and populate
	subTexesCount = 0;
	char* names = &m_subTexNames[0];
	ANKI_CHECK(subTexesEl.getChildElement("subTexture", subTexEl));
	do
	{
		ANKI_CHECK(subTexEl.getChildElement("name", el));
		CString name;
		ANKI_CHECK(el.getText(name));

		memcpy(names, &name[0], name.getLength() + 1);

		m_subTexes[subTexesCount].m_name = names;

		ANKI_CHECK(subTexEl.getChildElement("uv", el));
		Vec4 uv;
		ANKI_CHECK(el.getVec4(uv));
		m_subTexes[subTexesCount].m_uv = {{uv[0], uv[1], uv[2], uv[3]}};

		names += name.getLength() + 1;
		++subTexesCount;

		ANKI_CHECK(subTexEl.getNextSiblingElement("subTexture", subTexEl));
	} while(subTexEl);

	return Error::NONE;
}