Files
2025-05-13 02:46:21 +03:00

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;
}
}