207 lines
4.6 KiB
C++
207 lines
4.6 KiB
C++
#include "shaders/IShaderGraph.h"
|
|
#include <Types.h>
|
|
#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;
|
|
}
|
|
} |