Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Glew include
Toshihiro Shimizu 890ddd
#include <gl glew.h=""></gl>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tmsgcore.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qglshaderprogram></qglshaderprogram>
Toshihiro Shimizu 890ddd
#include <qglshader></qglshader>
Toshihiro Shimizu 890ddd
#include <qdir></qdir>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx/shaderinterface.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(ShaderInterface, "ShaderInterface")
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(ShaderInterface::ParameterConcept, "ShaderInterface::ParameterConcept")
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(ShaderInterface::Parameter, "ShaderInterface::Parameter")
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(ShaderInterface::ShaderData, "ShaderInterface::ShaderData")
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
//    Local Namespace stuff
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Filescope declarations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::pair<qglshaderprogram *,="" qdatetime=""> CompiledShader;</qglshaderprogram>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct CaselessCompare {
Toshihiro Shimizu 890ddd
	const QString &m_str;
Toshihiro Shimizu 890ddd
	CaselessCompare(const QString &str) : m_str(str) {}
Toshihiro Shimizu 890ddd
	bool operator()(const QString &str) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return (m_str.compare(str, Qt::CaseInsensitive) == 0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Filescope variables
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const static QString l_typeNames[ShaderInterface::TYPESCOUNT] = {
Toshihiro Shimizu 890ddd
	"", "bool", "float", "vec2", "vec3", "vec4", "int", "ivec2", "ivec3", "ivec4", "rgba", "rgb"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const static QString l_conceptNames[ShaderInterface::CONCEPTSCOUNT] = {
Toshihiro Shimizu 890ddd
	"none", "percent", "length", "angle", "point", "radius_ui", "width_ui",
Toshihiro Shimizu 890ddd
	"angle_ui", "point_ui", "xy_ui", "vector_ui", "polar_ui", "size_ui", "quad_ui",
Toshihiro Shimizu 890ddd
	"rect_ui"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const static QString l_hwtNames[ShaderInterface::HWTCOUNT] = {
Toshihiro Shimizu 890ddd
	"none", "any", "isotropic"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum Names { MAIN_PROGRAM,
Toshihiro Shimizu 890ddd
			 INPUT_PORTS,
Toshihiro Shimizu 890ddd
			 INPUT_PORT,
Toshihiro Shimizu 890ddd
			 PORTS_PROGRAM,
Toshihiro Shimizu 890ddd
			 PARAMETERS,
Toshihiro Shimizu 890ddd
			 PARAMETER,
Toshihiro Shimizu 890ddd
			 NAME,
Toshihiro Shimizu 890ddd
			 PROGRAM_FILE,
Toshihiro Shimizu 890ddd
			 CONCEPT,
Toshihiro Shimizu 890ddd
			 DEFAULT_,
Toshihiro Shimizu 890ddd
			 RANGE,
Toshihiro Shimizu 890ddd
			 HANDLED_WORLD_TRANSFORMS,
Toshihiro Shimizu 890ddd
			 BBOX_PROGRAM,
Toshihiro Shimizu 890ddd
			 NAMESCOUNT };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const static std::string l_names[NAMESCOUNT] = {
Toshihiro Shimizu 890ddd
	"MainProgram", "InputPorts", "InputPort", "PortsProgram", "Parameters", "Parameter",
Toshihiro Shimizu 890ddd
	"Name", "ProgramFile", "Concept", "Default", "Range", "HandledWorldTransforms",
Toshihiro Shimizu 890ddd
	"BBoxProgram"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Filescope functions
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool loadShader(QGLShader::ShaderType type, const TFilePath &fp, CompiledShader &cs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QGLShader *shader = new QGLShader(type, cs.first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const QString &qfp = QString::fromStdWString(fp.getWideString());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QFileInfo shaderFileInfo(qfp);
Toshihiro Shimizu 890ddd
	cs.second = shaderFileInfo.lastModified();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return shader->compileSourceFile(qfp) &&
Toshihiro Shimizu 890ddd
		   cs.first->addShader(shader);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void dumpError(TIStream &is, const std::wstring &err = std::wstring())
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	DVGui::info(
Toshihiro Shimizu 890ddd
		"Error reading " + QString::fromStdWString(is.getFilePath().getLevelNameW()) +
Toshihiro Shimizu 890ddd
		" (line " + QString::number(is.getLine()) + ")" +
Toshihiro Shimizu 890ddd
		(err.empty() ? QString() : QString::fromStdWString(L": " + err)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void skipTag(TIStream &is, const std::string &tagName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	DVGui::info(
Toshihiro Shimizu 890ddd
		"Error reading " + QString::fromStdWString(is.getFilePath().getLevelNameW()) +
Toshihiro Shimizu 890ddd
		" (line " + QString::number(is.getLine()) +
Toshihiro Shimizu 890ddd
		"): Unknown tag '<" + QString::fromStdString(tagName) + ">'");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	is.skipCurrentTag();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
//    ShaderInterface  implementation
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ShaderInterface::ShaderInterface()
Toshihiro Shimizu 890ddd
	: m_hwt(ANY)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::clear()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_mainShader = m_portsShader = ShaderData();
Toshihiro Shimizu 890ddd
	m_parameters.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool ShaderInterface::isValid() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_mainShader.isValid();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const std::vector<shaderinterface::parameter> &</shaderinterface::parameter>
Toshihiro Shimizu 890ddd
ShaderInterface::parameters() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_parameters;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const std::vector<qstring> &ShaderInterface::inputPorts() const</qstring>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_ports;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const ShaderInterface::ShaderData &ShaderInterface::mainShader() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_mainShader;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const ShaderInterface::ShaderData &ShaderInterface::inputPortsShader() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_portsShader;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const ShaderInterface::ShaderData &ShaderInterface::bboxShader() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_bboxShader;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ShaderInterface::HandledWorldTransformsType ShaderInterface::hwtType() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_hwt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::pair<qglshaderprogram *,="" qdatetime=""></qglshaderprogram>
Toshihiro Shimizu 890ddd
ShaderInterface::makeProgram(const ShaderData &sd,
Toshihiro Shimizu 890ddd
							 int varyingsCount, const GLchar **varyingNames) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	CompiledShader result;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isValid())
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	result.first = new QGLShaderProgram;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	::loadShader(sd.m_type, sd.m_path, result);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (varyingsCount > 0)
Toshihiro Shimizu 890ddd
		glTransformFeedbackVaryings(result.first->programId(), varyingsCount, varyingNames, GL_INTERLEAVED_ATTRIBS);
Toshihiro Shimizu 890ddd
	// NOTE: Since we'll be drawing a single vertex, GL_INTERLEAVED_ATTRIBS is less restrictive than GL_SEPARATE_ATTRIBS.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	result.first->link();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		inline static TFilePath getRelativePath(const TFilePath &file, const TFilePath &relTo)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			QDir relToDir(QString::fromStdWString(relTo.getParentDir().getWideString()));
Toshihiro Shimizu 890ddd
			QString relFileStr(relToDir.relativeFilePath(QString::fromStdWString(file.getWideString())));
Toshihiro Shimizu 890ddd
			return TFilePath(relFileStr.toStdWString());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(isValid());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (isValid()) {
Toshihiro Shimizu 890ddd
		os.openChild(l_names[MAIN_PROGRAM]);
Toshihiro Shimizu 890ddd
		os << m_mainShader;
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		os.openChild(l_names[INPUT_PORTS]);
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			int i, iCount = int(m_ports.size());
Toshihiro Shimizu 890ddd
			for (i = 0; i != iCount; ++i) {
Toshihiro Shimizu 890ddd
				os.openChild(l_names[INPUT_PORT]);
Toshihiro Shimizu 890ddd
				os << m_ports[i];
Toshihiro Shimizu 890ddd
				os.closeChild();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (m_portsShader.isValid()) {
Toshihiro Shimizu 890ddd
				os.openChild(l_names[PORTS_PROGRAM]);
Toshihiro Shimizu 890ddd
				os << m_portsShader;
Toshihiro Shimizu 890ddd
				os.closeChild();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_bboxShader.isValid()) {
Toshihiro Shimizu 890ddd
			os.openChild(l_names[BBOX_PROGRAM]);
Toshihiro Shimizu 890ddd
			os << m_bboxShader;
Toshihiro Shimizu 890ddd
			os.closeChild();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_hwt != ANY) {
Toshihiro Shimizu 890ddd
			os.openChild(l_names[HANDLED_WORLD_TRANSFORMS]);
Toshihiro Shimizu 890ddd
			os << l_names[m_hwt];
Toshihiro Shimizu 890ddd
			os.closeChild();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		os.openChild(l_names[PARAMETERS]);
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			int p, pCount = int(m_parameters.size());
Toshihiro Shimizu 890ddd
			for (p = 0; p != pCount; ++p) {
Toshihiro Shimizu 890ddd
				os.openChild(l_names[PARAMETER]);
Toshihiro Shimizu 890ddd
				os << m_parameters[p];
Toshihiro Shimizu 890ddd
				os.closeChild();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		inline static TFilePath getAbsolutePath(const TFilePath &file, const TFilePath &relTo)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			QDir relToDir(QString::fromStdWString(relTo.getParentDir().getWideString()));
Toshihiro Shimizu 890ddd
			QString absFileStr(relToDir.absoluteFilePath(QString::fromStdWString(file.getWideString())));
Toshihiro Shimizu 890ddd
			return TFilePath(absFileStr.toStdWString());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static bool nameMatch(const QString &name, const Parameter ¶m)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			return (name == param.m_name);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
			if (tagName == l_names[MAIN_PROGRAM]) {
Toshihiro Shimizu 890ddd
				is >> m_mainShader;
Toshihiro Shimizu 890ddd
				m_mainShader.m_type = QGLShader::Fragment;
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else if (tagName == l_names[INPUT_PORTS]) {
Toshihiro Shimizu 890ddd
				while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
					if (tagName == l_names[INPUT_PORT]) {
Toshihiro Shimizu 890ddd
						QString portName;
Toshihiro Shimizu 890ddd
						is >> portName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						m_ports.push_back(portName);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						is.closeChild();
Toshihiro Shimizu 890ddd
					} else if (tagName == l_names[PORTS_PROGRAM]) {
Toshihiro Shimizu 890ddd
						is >> m_portsShader;
Toshihiro Shimizu 890ddd
						m_portsShader.m_type = QGLShader::Vertex;
Toshihiro Shimizu 890ddd
						is.closeChild();
Toshihiro Shimizu 890ddd
					} else
Toshihiro Shimizu 890ddd
						::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else if (tagName == l_names[BBOX_PROGRAM]) {
Toshihiro Shimizu 890ddd
				is >> m_bboxShader;
Toshihiro Shimizu 890ddd
				m_bboxShader.m_type = QGLShader::Vertex;
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else if (tagName == l_names[HANDLED_WORLD_TRANSFORMS]) {
Toshihiro Shimizu 890ddd
				QString hwtName;
Toshihiro Shimizu 890ddd
				is >> hwtName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				m_hwt = HandledWorldTransformsType(std::find_if(
Toshihiro Shimizu 890ddd
													   l_hwtNames, l_hwtNames + HWTCOUNT, ::CaselessCompare(hwtName)) -
Toshihiro Shimizu 890ddd
												   l_hwtNames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (m_hwt == HWTCOUNT) {
Toshihiro Shimizu 890ddd
					m_hwt = HWT_UNKNOWN;
Toshihiro Shimizu 890ddd
					::dumpError(is, L"Unrecognized HandledWorldTransforms type '" + hwtName.toStdWString() + L"'");
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else if (tagName == l_names[PARAMETERS]) {
Toshihiro Shimizu 890ddd
				while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
					if (tagName == l_names[PARAMETER]) {
Toshihiro Shimizu 890ddd
						Parameter param;
Toshihiro Shimizu 890ddd
						is >> param;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						m_parameters.push_back(param);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						is.closeChild();
Toshihiro Shimizu 890ddd
					} else
Toshihiro Shimizu 890ddd
						::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else if (tagName == l_names[CONCEPT]) {
Toshihiro Shimizu 890ddd
				ParameterConcept concept;
Toshihiro Shimizu 890ddd
				is >> concept;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				m_parConcepts.push_back(concept);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				is.closeChild();
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
	} catch (const TException &e) {
Toshihiro Shimizu 890ddd
		::dumpError(is, e.getMessage());
Toshihiro Shimizu 890ddd
		clear();
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		::dumpError(is);
Toshihiro Shimizu 890ddd
		clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
//    ShaderInterface::ShaderData  implementation
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::ShaderData::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		inline static TFilePath getRelativePath(const TFilePath &file, const TFilePath &relTo)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			QDir relToDir(QString::fromStdWString(relTo.getParentDir().getWideString()));
Toshihiro Shimizu 890ddd
			QString relFileStr(relToDir.relativeFilePath(QString::fromStdWString(file.getWideString())));
Toshihiro Shimizu 890ddd
			return TFilePath(relFileStr.toStdWString());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.openChild(l_names[NAME]);
Toshihiro Shimizu 890ddd
	os << m_name;
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.openChild(l_names[PROGRAM_FILE]);
Toshihiro Shimizu 890ddd
	os << locals::getRelativePath(m_path, os.getFilePath());
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::ShaderData::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		inline static TFilePath getAbsolutePath(const TFilePath &file, const TFilePath &relTo)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			QDir relToDir(QString::fromStdWString(relTo.getParentDir().getWideString()));
Toshihiro Shimizu 890ddd
			QString absFileStr(relToDir.absoluteFilePath(QString::fromStdWString(file.getWideString())));
Toshihiro Shimizu 890ddd
			return TFilePath(absFileStr.toStdWString());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == l_names[NAME])
Toshihiro Shimizu 890ddd
			is >> m_name, is.closeChild();
Toshihiro Shimizu 890ddd
		else if (tagName == l_names[PROGRAM_FILE]) {
Toshihiro Shimizu 890ddd
			is >> m_path;
Toshihiro Shimizu 890ddd
			m_path = locals::getAbsolutePath(m_path, is.getFilePath());
Toshihiro Shimizu 890ddd
			is.closeChild();
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
//    ShaderInterface::ParameterConcept  implementation
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::ParameterConcept::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	os << l_conceptNames[m_type];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_label.isEmpty()) {
Toshihiro Shimizu 890ddd
		os.openChild(l_names[NAME]);
Toshihiro Shimizu 890ddd
		os << m_label;
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int n, nCount = int(m_parameterNames.size());
Toshihiro Shimizu 890ddd
	for (n = 0; n != nCount; ++n) {
Toshihiro Shimizu 890ddd
		os.openChild(l_names[PARAMETER]);
Toshihiro Shimizu 890ddd
		os << m_parameterNames[n];
Toshihiro Shimizu 890ddd
		os.closeChild();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::ParameterConcept::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Read the concept type
Toshihiro Shimizu 890ddd
	QString conceptName;
Toshihiro Shimizu 890ddd
	is >> conceptName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_type = ParameterConceptType(std::find_if(
Toshihiro Shimizu 890ddd
									  l_conceptNames, l_conceptNames + CONCEPTSCOUNT, ::CaselessCompare(conceptName)) -
Toshihiro Shimizu 890ddd
								  l_conceptNames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_type == CONCEPTSCOUNT) {
Toshihiro Shimizu 890ddd
		m_type = CONCEPT_NONE;
Toshihiro Shimizu 890ddd
		::dumpError(is, L"Unrecognized concept type '" + conceptName.toStdWString() + L"'");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Read any associated parameter names
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == l_names[PARAMETER]) {
Toshihiro Shimizu 890ddd
			QString name;
Toshihiro Shimizu 890ddd
			is >> name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_parameterNames.push_back(name);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.closeChild();
Toshihiro Shimizu 890ddd
		} else if (tagName == l_names[NAME])
Toshihiro Shimizu 890ddd
			is >> m_label, is.closeChild();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
//    ShaderInterface::Parameter  implementation
Toshihiro Shimizu 890ddd
//**********************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::Parameter::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	os << l_typeNames[m_type] << m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.openChild(l_names[CONCEPT]);
Toshihiro Shimizu 890ddd
	os << m_concept;
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.openChild(l_names[DEFAULT_]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (m_type) {
Toshihiro Shimizu 890ddd
	case BOOL:
Toshihiro Shimizu 890ddd
		os << (int)m_default.m_bool;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case FLOAT:
Shinya Kitaoka d4642c
		os << (double)m_default.m_float;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC2:
Shinya Kitaoka d4642c
		os << (double)m_default.m_vec2[0] << (double)m_default.m_vec2[1];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC3:
Shinya Kitaoka d4642c
		os << (double)m_default.m_vec3[0] << (double)m_default.m_vec3[1]
Shinya Kitaoka d4642c
			<< (double)m_default.m_vec3[2];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC4:
Shinya Kitaoka d4642c
		os << (double)m_default.m_vec4[0] << (double)m_default.m_vec4[1]
Shinya Kitaoka d4642c
			<< (double)m_default.m_vec4[2]
Shinya Kitaoka d4642c
			<< (double)m_default.m_vec4[3];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case INT:
Shinya Kitaoka d4642c
		os << m_default.m_int;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC2:
Shinya Kitaoka d4642c
		os << m_default.m_ivec2[0] << m_default.m_ivec2[1];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC3:
Shinya Kitaoka d4642c
		os << m_default.m_ivec3[0] << m_default.m_ivec3[1]
Shinya Kitaoka d4642c
			<< m_default.m_ivec3[2];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC4:
Shinya Kitaoka d4642c
		os << m_default.m_ivec4[0] << m_default.m_ivec4[1]
Shinya Kitaoka d4642c
			<< m_default.m_ivec4[2]
Shinya Kitaoka d4642c
			<< m_default.m_ivec4[3];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case RGBA:
Shinya Kitaoka d4642c
		os << (int)m_default.m_rgba[0] << (int)m_default.m_rgba[1]
Shinya Kitaoka d4642c
			<< (int)m_default.m_rgba[2]
Shinya Kitaoka d4642c
			<< (int)m_default.m_rgba[3];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case RGB:
Shinya Kitaoka d4642c
		os << (int)m_default.m_rgb[0] << (int)m_default.m_rgb[1]
Shinya Kitaoka d4642c
			<< (int)m_default.m_rgb[2];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.openChild(l_names[RANGE]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (m_type) {
Toshihiro Shimizu 890ddd
	case FLOAT:
Toshihiro Shimizu 890ddd
		os << (double)m_range[0].m_float << (double)m_range[1].m_float;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC2:
Shinya Kitaoka d4642c
		os << (double)m_range[0].m_vec2[0] << (double)m_range[1].m_vec2[0]
Shinya Kitaoka d4642c
					  << (double)m_range[0].m_vec2[1]
Shinya Kitaoka d4642c
					  << (double)m_range[1].m_vec2[1];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC3:
Shinya Kitaoka d4642c
		os << (double)m_range[0].m_vec3[0] << (double)m_range[1].m_vec3[0]
Toshihiro Shimizu 890ddd
					   << (double)m_range[0].m_vec3[1]
Toshihiro Shimizu 890ddd
					   << (double)m_range[1].m_vec3[1]
Toshihiro Shimizu 890ddd
					   << (double)m_range[0].m_vec3[2]
Toshihiro Shimizu 890ddd
					   << (double)m_range[1].m_vec3[2];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC4:
Shinya Kitaoka d4642c
		os << (double)m_range[0].m_vec4[0] << (double)m_range[1].m_vec4[0]
Shinya Kitaoka d4642c
					  << (double)m_range[0].m_vec4[1]
Shinya Kitaoka d4642c
					  << (double)m_range[1].m_vec4[1]
Shinya Kitaoka d4642c
					  << (double)m_range[0].m_vec4[2]
Shinya Kitaoka d4642c
					  << (double)m_range[1].m_vec4[2]
Shinya Kitaoka d4642c
					  << (double)m_range[0].m_vec4[3]
Shinya Kitaoka d4642c
					  << (double)m_range[1].m_vec4[3];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case INT:
Shinya Kitaoka d4642c
		os << m_range[0].m_int << m_range[1].m_int;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC2:
Shinya Kitaoka d4642c
		os << m_range[0].m_ivec2[0] << m_range[1].m_ivec2[0]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec2[1]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec2[1];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC3:
Shinya Kitaoka d4642c
		os << m_range[0].m_ivec3[0] << m_range[1].m_ivec3[0]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec3[1]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec3[1]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec3[2]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec3[2];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC4:
Shinya Kitaoka d4642c
		os << m_range[0].m_ivec4[0] << m_range[1].m_ivec4[0]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec4[1]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec4[1]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec4[2]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec4[2]
Toshihiro Shimizu 890ddd
						<< m_range[0].m_ivec4[3]
Toshihiro Shimizu 890ddd
						<< m_range[1].m_ivec4[3];
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	os.closeChild();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ShaderInterface::Parameter::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// Load type and name
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QString typeName;
Toshihiro Shimizu 890ddd
	is >> typeName >> m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_type = ShaderInterface::ParameterType(std::find_if(
Toshihiro Shimizu 890ddd
												l_typeNames, l_typeNames + TYPESCOUNT, ::CaselessCompare(typeName)) -
Toshihiro Shimizu 890ddd
											l_typeNames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_type == TYPESCOUNT)
Toshihiro Shimizu 890ddd
		throw TException(L"Unrecognized parameter type '" + typeName.toStdWString() + L"'");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Load range
Toshihiro Shimizu 890ddd
	std::string tagName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Initialize default values
Toshihiro Shimizu 890ddd
	m_concept = ParameterConcept();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (m_type) {
Toshihiro Shimizu 890ddd
	case BOOL:
Toshihiro Shimizu 890ddd
		m_default.m_bool = false;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case FLOAT:
Shinya Kitaoka d4642c
		m_default.m_float = 0.0;
Shinya Kitaoka d4642c
		m_range[0].m_float = -(std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		m_range[1].m_float = (std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC2:
Shinya Kitaoka d4642c
		m_default.m_vec2[0] = m_default.m_vec2[1] = 0.0;
Shinya Kitaoka d4642c
		m_range[0].m_vec2[0] = m_range[0].m_vec2[1] = -(std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		m_range[1].m_vec2[0] = m_range[1].m_vec2[1] = (std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC3:
Shinya Kitaoka d4642c
		m_default.m_vec3[0] = m_default.m_vec3[1] = m_default.m_vec3[1] = 0.0;
Shinya Kitaoka d4642c
		m_range[0].m_vec3[0] = m_range[0].m_vec3[1] = m_range[0].m_vec3[2] = -(std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		m_range[1].m_vec3[0] = m_range[1].m_vec3[1] = m_range[1].m_vec3[2] = (std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case VEC4:
Shinya Kitaoka d4642c
		m_default.m_vec4[0] = m_default.m_vec4[1] =
Shinya Kitaoka d4642c
			m_default.m_vec4[1] = m_default.m_vec4[1] = 0.0;
Shinya Kitaoka d4642c
		m_range[0].m_vec4[0] = m_range[0].m_vec4[1] =
Shinya Kitaoka d4642c
			m_range[0].m_vec4[2] = m_range[0].m_vec4[3] = -(std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		m_range[1].m_vec4[0] = m_range[1].m_vec4[1] =
Shinya Kitaoka d4642c
			m_range[1].m_vec4[2] = m_range[1].m_vec4[3] = (std::numeric_limits<glfloat>::max)();</glfloat>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case INT:
Shinya Kitaoka d4642c
		m_default.m_int = 0;
Shinya Kitaoka d4642c
		m_range[0].m_int = -(std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		m_range[1].m_int = (std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC2:
Shinya Kitaoka d4642c
		m_default.m_ivec2[0] = m_default.m_ivec2[1] = 0;
Shinya Kitaoka d4642c
		m_range[0].m_ivec2[0] = m_range[0].m_ivec2[1] = -(std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		m_range[1].m_ivec2[0] = m_range[1].m_ivec2[1] = (std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC3:
Shinya Kitaoka d4642c
		m_default.m_ivec3[0] = m_default.m_ivec3[1] = m_default.m_ivec3[1] = 0;
Shinya Kitaoka d4642c
		m_range[0].m_ivec3[0] = m_range[0].m_ivec3[1] = m_range[0].m_ivec3[2] = -(std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		m_range[1].m_ivec3[0] = m_range[1].m_ivec3[1] = m_range[1].m_ivec3[2] = (std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case IVEC4:
Shinya Kitaoka d4642c
		m_default.m_ivec4[0] = m_default.m_ivec4[1] =
Shinya Kitaoka d4642c
			m_default.m_ivec4[1] = m_default.m_ivec4[1] = 0;
Shinya Kitaoka d4642c
		m_range[0].m_ivec4[0] = m_range[0].m_ivec4[1] =
Shinya Kitaoka d4642c
			m_range[0].m_ivec4[2] = m_range[0].m_ivec4[3] = -(std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		m_range[1].m_ivec4[0] = m_range[1].m_ivec4[1] =
Shinya Kitaoka d4642c
			m_range[1].m_ivec4[2] = m_range[1].m_ivec4[3] = (std::numeric_limits<glint>::max)();</glint>
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case RGBA:
Shinya Kitaoka d4642c
		m_default.m_rgba[0] = m_default.m_rgba[1] =
Shinya Kitaoka d4642c
			m_default.m_rgba[2] = m_default.m_rgba[3] = 255;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case RGB:
Shinya Kitaoka d4642c
		m_default.m_rgb[0] = m_default.m_rgb[1] =
Shinya Kitaoka d4642c
			m_default.m_rgb[2] = 255;
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Attempt loading range from file
Toshihiro Shimizu 890ddd
	while (is.openChild(tagName)) {
Toshihiro Shimizu 890ddd
		if (tagName == l_names[CONCEPT])
Toshihiro Shimizu 890ddd
			is >> m_concept, is.closeChild();
Toshihiro Shimizu 890ddd
		else if (tagName == l_names[DEFAULT_]) {
Toshihiro Shimizu 890ddd
			switch (m_type) {
Toshihiro Shimizu 890ddd
			case BOOL: {
Toshihiro Shimizu 890ddd
				int val;
Toshihiro Shimizu 890ddd
				is >> val, m_default.m_bool = val;
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case FLOAT: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_float = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC2: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec2[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec2[1] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC3: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec3[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec3[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec3[2] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC4: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec4[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec4[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec4[2] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_vec4[3] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case INT:
Shinya Kitaoka d4642c
				is >> m_default.m_int;
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case IVEC2:
Shinya Kitaoka d4642c
				is >> m_default.m_ivec2[0] >> m_default.m_ivec2[1];
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case IVEC3:
Shinya Kitaoka d4642c
				is >> m_default.m_ivec3[0] >> m_default.m_ivec3[1] >> m_default.m_ivec3[2];
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case IVEC4:
Shinya Kitaoka d4642c
				is >> m_default.m_ivec4[0] >> m_default.m_ivec4[1] >> m_default.m_ivec4[2] >> m_default.m_ivec4[3];
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case RGBA: {
Shinya Kitaoka d4642c
				int val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgba[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgba[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgba[2] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgba[3] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case RGB: {
Shinya Kitaoka d4642c
				int val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgb[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgb[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_default.m_rgb[2] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.closeChild();
Toshihiro Shimizu 890ddd
		} else if (tagName == l_names[RANGE]) {
Toshihiro Shimizu 890ddd
			switch (m_type) {
Toshihiro Shimizu 890ddd
			case FLOAT: {
Toshihiro Shimizu 890ddd
				double val;
Toshihiro Shimizu 890ddd
				is >> val, m_range[0].m_float = val;
Toshihiro Shimizu 890ddd
				is >> val, m_range[1].m_float = val;
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC2: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec2[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec2[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec2[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec2[1] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC3: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec3[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec3[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec3[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec3[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec3[2] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec3[2] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case VEC4: {
Shinya Kitaoka d4642c
				double val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec4[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec4[0] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec4[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec4[1] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec4[2] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec4[2] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[0].m_vec4[3] = val;
Shinya Kitaoka d4642c
				is >> val, m_range[1].m_vec4[3] = val;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
			case INT:
Shinya Kitaoka d4642c
				is >> m_range[0].m_int >> m_range[1].m_int;
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
Shinya Kitaoka d4642c
			case IVEC2:
Shinya Kitaoka d4642c
				is >> m_range[0].m_ivec2[0] >> m_range[1].m_ivec2[0]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec2[1] >> m_range[1].m_ivec2[1];
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
Shinya Kitaoka d4642c
			case IVEC3:
Shinya Kitaoka d4642c
				is >> m_range[0].m_ivec3[0] >> m_range[1].m_ivec3[0]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec3[1] >> m_range[1].m_ivec3[1]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec3[2] >> m_range[1].m_ivec3[2];
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
Shinya Kitaoka d4642c
			case IVEC4:
Shinya Kitaoka d4642c
				is >> m_range[0].m_ivec4[0] >> m_range[1].m_ivec4[0]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec4[1] >> m_range[1].m_ivec4[1]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec4[2] >> m_range[1].m_ivec4[2]
Shinya Kitaoka d4642c
					>> m_range[0].m_ivec4[3] >> m_range[1].m_ivec4[3];
Shinya Kitaoka d4642c
				break;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			is.closeChild();
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			::skipTag(is, tagName);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Post-process loaded data
Toshihiro Shimizu 890ddd
	if (m_concept.m_label.isEmpty())
Toshihiro Shimizu 890ddd
		m_concept.m_label = m_name;
Toshihiro Shimizu 890ddd
}