#include "shaders/IShaderGraph.h" #include #include "XML.h" #define NAME_LENGTH 64 namespace LifeGraphics { IShaderGraph::IShaderGraph(IShaderGraphNodeFactory* factory) :last_id(0) { pFactory = factory; for(int i = 0; i < 16; i++) { texture_slots[i] = -1; } } IShaderGraph::~IShaderGraph() { } int IShaderGraph::GrabTextureSlot() { for(int i = 0; i < 16; i++) { if(texture_slots[i] == -1) { texture_slots[i] = 1; return i; } } return -1; } IShaderGraphNode* IShaderGraph::AddNode(const String& name) { IShaderGraphNode* node = pFactory->Build(name); node->id = GetID(); Nodes.push_back(node); if(name == STR("SrcTex2D")) { node->resource_id = GrabTextureSlot(); } return node; } bool IShaderGraph::DeleteNode(int id) { for(NodeCollectionIt it = Nodes.begin(); it != Nodes.end(); ++it) { IShaderGraphNode* n = (*it); if(n->id == id) { //deactivate output links for(int j = 0; j < n->Outputs.size(); j++){ IShaderGraphNodePort* port = n->Outputs[j]; port->BreakLink(); delete port; } //deactivate input links for(int j = 0; j < n->Inputs.size(); j++){ IShaderGraphNodePort* port = n->Inputs[j]; port->BreakLink(); delete port; } delete (*it); Nodes.erase(it); return true; } } return false; } IShaderGraphNode* IShaderGraph::GetNodeByID(int id) { int nc = Nodes.size(); for(int i = 0; i < nc; i++) { if(Nodes[i]->id == id) return Nodes[i]; } return 0; } void IShaderGraph::Clear() { int nc = Nodes.size(); for(int i = 0; i < nc; i++) { delete Nodes[i]; } Nodes.clear(); } IShaderGraphNode* IShaderGraph::GetNodeByArrayID(int id) { int nc = Nodes.size(); if(id < nc) { return Nodes[id]; } return nullptr; } size_t IShaderGraph::GetNodeCount() { return Nodes.size(); } void IShaderGraph::SerializeXML(LifeCore::IMemoryStream* stm) { /*int node_count = Nodes.size(); pugi::xml_document doc; pugi::xml_node rootNode = doc.append_child("ShaderGraph"); rootNode.append_attribute("NodeCount") = node_count; rootNode.append_attribute("LastID") = last_id; //write node info for(int i = 0; i < node_count; i++) { IShaderGraphNode* n = Nodes[i]; pugi::xml_node node = rootNode.append_child("Node"); node.append_attribute("Name") = n->Name; node.append_attribute("ID") = n->id; }*/ } bool IShaderGraph::DeserializeXML(LifeCore::IMemoryStream* stm) { return true; } void IShaderGraph::Serialize(LifeCore::IMemoryStream* stm) { int node_count = Nodes.size(); //write total nodes count stm->Write(node_count); //write last id value stm->Write(last_id); //write basic node info for(int i = 0; i < node_count; i++){ IShaderGraphNode* n = Nodes[i]; StringSerialize(n->Name, stm); stm->Write(n->id); } //write advanced node info for(int i = 0; i < node_count; i++){ IShaderGraphNode* n = Nodes[i]; n->Serialize(stm); //serialize properties for(int j = 0; j < n->Inputs.size(); j++){ IShaderGraphNodePort* port = n->Inputs[j]; int val = -1; int parent = -1; if(port->GetLinkCount()){ val = port->GetLink(0)->Parent->GetOutputID(port->GetLink(0)); parent = port->GetLink(0)->Parent->id; } //write attached node ID stm->Write(parent); //write attached node port ID stm->Write(val); } } } bool IShaderGraph::Deserialize(LifeCore::IMemoryStream* stm) { int node_count; stm->ReadInt32(node_count); stm->ReadInt32(last_id); //read basic info and create nodes for(int i = 0; i < node_count; i++){ //get node name String name = StringDeserialize(stm); IShaderGraphNode* n = pFactory->Build(name); //get node ID stm->ReadInt32(n->id); Nodes.push_back(n); } //read extended info for(int i = 0; i < node_count; i++){ IShaderGraphNode* n = Nodes[i]; n->Deserialize(stm); //deserialize properties int pc = n->Inputs.size(); //read ports info for(int j = 0; j < pc; j++){ int nid, pid; //read attached node id stm->ReadInt32(nid); //read attached port id stm->ReadInt32(pid); //if attached - make link if(pid != -1){ //current node IShaderGraphNode* cn = Nodes[i]; //attachment node IShaderGraphNode* an = GetNodeByID(nid); cn->Inputs[j]->MakeLink(cn->Inputs[j], an->Outputs[pid]); } } } return true; } }