summaryrefslogtreecommitdiff
path: root/hw3/src/sceneIO_material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hw3/src/sceneIO_material.cpp')
-rw-r--r--hw3/src/sceneIO_material.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/hw3/src/sceneIO_material.cpp b/hw3/src/sceneIO_material.cpp
new file mode 100644
index 0000000..018e913
--- /dev/null
+++ b/hw3/src/sceneIO_material.cpp
@@ -0,0 +1,147 @@
+/******************************************************************/
+/* This file is part of the homework assignments for CSCI-427/527 */
+/* at The College of William & Mary and authored by Pieter Peers. */
+/* No part of this file, whether altered or in original form, can */
+/* be distributed or used outside the context of CSCI-427/527 */
+/* without consent of either the College of William & Mary or */
+/* Pieter Peers. */
+/******************************************************************/
+#include <cassert>
+
+#include "sceneIO_xml.h"
+#include "sceneIO_core.h"
+#include "sceneIO_material.h"
+
+#include "compoundShader.h"
+#include "reflectanceParameter.h"
+#include "phongReflectanceShader.h"
+#include "diffuseReflectanceShader.h"
+
+//////////////////////////////////////////////////////////////
+static colorReflectanceParameter importColorReflectanceParameter(const XMLNode& node, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ // get parameter
+ color value = getColor(node, "value", color(0.0f, 0.0f, 0.0f));
+
+ // create & return parameter, give preference to textured parameters
+ return colorReflectanceParameter(value);
+
+ // Done.
+}
+
+//////////////////////////////////////////////////////////////
+static scalarReflectanceParameter importScalarReflectanceParameter(const XMLNode& node, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ // get parameters
+ float value = getFloat(node, "value", 0.0f);
+ unsigned int channel = getInteger(node, "channel", 0);
+
+ // create & return parameter, give preference to textured parameters
+ return scalarReflectanceParameter(value);
+
+ // Done.
+}
+
+//////////////////////////////////////////////////////////////
+static std::shared_ptr<shader_base> importDiffuse(const XMLNode& node, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ // sanity check
+ assert(node.name() == "diffuse");
+
+ // parameter storage
+ colorReflectanceParameter albedo;
+
+ // check child nodes
+ for(XMLNode child=node.firstChild(); child.isValid(); child++)
+ {
+ std::string name = child.name();
+ if(name == "albedo") albedo = importColorReflectanceParameter(child, texture_cache, rootDir);
+ else errorMessage("Unknown parameter in diffuse-node (%s).", name.c_str());
+ }
+
+ // Done.
+ return std::shared_ptr<shader_base>(new diffuseReflectanceShader(albedo));
+}
+
+//////////////////////////////////////////////////////////////
+static std::shared_ptr<shader_base> importPhong(const XMLNode& node, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ // sanity check
+ assert(node.name() == "phong");
+
+ // parameter storage
+ colorReflectanceParameter albedo;
+ scalarReflectanceParameter sharpness;
+
+ // check child nodes
+ for(XMLNode child=node.firstChild(); child.isValid(); child++)
+ {
+ std::string name = child.name();
+ if(name == "albedo") albedo = importColorReflectanceParameter(child, texture_cache, rootDir);
+ else if(name == "sharpness") sharpness = importScalarReflectanceParameter(child, texture_cache, rootDir);
+ else errorMessage("Unknown parameter in phong-node (%s).", name.c_str());
+ }
+
+ // Done.
+ return std::shared_ptr<shader_base>(new phongReflectanceShader(albedo, sharpness));
+}
+
+//////////////////////////////////////////////////////////////
+static std::shared_ptr<shader_base> importCompoundMaterial(const XMLNode& node, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ // sanity check
+ assert(node.isValid() && node.name() == "material");
+
+ // storage for child material nodes
+ std::vector<std::shared_ptr<const shader_base>> shader_list;
+
+ // for each child
+ for(XMLNode child = node.firstChild(); child.isValid(); child++)
+ {
+ // try to import material
+ std::shared_ptr<shader_base> shader = importMaterial(child, shader_cache, texture_cache, rootDir);
+
+ // add to list if successful.
+ if(shader) shader_list.push_back(shader);
+ else errorMessage("Unknown material-node (%s).", child.name().c_str());
+ }
+
+ // Done.
+ return std::shared_ptr<shader_base>(new compoundShader(shader_list));
+}
+
+
+//////////////////////////////////////////////////////////////
+std::shared_ptr<shader_base> importMaterial(const XMLNode& node, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
+{
+ std::string name = node.name();
+
+ // check material type
+ if(name != "material" &&
+ name != "diffuse" &&
+ name != "phong") return std::shared_ptr<shader_base>(nullptr);
+
+ // check if reference
+ std::string ref = getString(node, "ref");
+ std::shared_ptr<shader_base> shader = shader_cache.get(ref);
+ if(shader) return shader;
+ else if(ref != "") errorMessage("Unknown %s name (%s).", name.c_str(), ref.c_str());
+
+ // get id
+ std::string id = getString(node, "id");
+ if(shader_cache.get(id))
+ errorMessage("%s-id is not unique (%s).", name.c_str(), id.c_str());
+
+ // process primitives based on type
+ if(name == "material") shader = importCompoundMaterial(node, shader_cache, texture_cache, rootDir);
+ else if(name == "diffuse") shader = importDiffuse(node, shader_cache, texture_cache, rootDir);
+ else if(name == "phong") shader = importPhong(node, shader_cache, texture_cache, rootDir);
+ else errorMessage("Unknown material-node (%s).", name.c_str());
+
+ // update cache
+ if(id != "") shader_cache.add(id, shader);
+
+ // Done.
+ return shader;
+}
+