using Godot; using System.Collections.Generic; namespace Rokojori { public class RDShaderProcessor:RGGraphProcessor { protected string _shaderPath; public RDShaderProcessor( RDGraph graph, string shaderPath ):base( graph ) { this._shaderPath = shaderPath; } protected RDShader _shader; protected RDPipeline _pipeline; protected RDPushConstants _constants = new RDPushConstants(); public RDPushConstants constants => _constants; protected Vector3I _groupSize = new Vector3I( 8, 8, 0 ); protected List _textureSlots = new List(); protected override void OnInitialize() { graph.context.Verbose( GetType().Name, "Trying to load shader: ", _shaderPath ); if ( _shaderPath == null ) { graph.context.Error( GetType().Name, "_shaderPath == null" ); return; } var glslFile = GD.Load( _shaderPath ); if ( glslFile == null ) { graph.context.Error( GetType().Name, "Couldn't load shader at path:", _shaderPath ); return; } _shader = RDShader.CreateFromSpirV( graph.context, glslFile.GetSpirV() ); if ( _shader == null ) { graph.context.Error( GetType().Name, "Couldn't create shader from code, path:", _shaderPath ); return; } _pipeline = RDPipeline.Create( graph.context, _shader ); if ( _shader == null ) { graph.context.Error( GetType().Name, "Couldn't create pipeline from compiled shader, path:", _shaderPath ); return; } graph.context.Verbose( GetType().Name, "Created shader at path: ", _shaderPath ); } public override void Process() { var context = graph.context; context.Clear(); context.CalculateSceneComputeGroups( _groupSize ); context.SetShaderAndPipeline( _shader, _pipeline ); context.Verbose( GetType().Name, "Setting texture uniforms", _textureSlots.Count ); int index = 0; _textureSlots.ForEach( t => { index++; t.ResolveTexture(); var texture = t.GetTexture(); if ( texture == null || ! texture.rid.IsValid ) { if ( texture == null ) { context.Error( index, "Texture is null" ); } else { context.Error( index, "Texture is not valid:", texture.rid ); } graph.context.AssignMissingTexture( t.sampler ); return; } graph.context.AssignTexture( texture, t.sampler ); } ); if ( _constants.size > 0 ) { context.Verbose( GetType().Name, "Setting constants", _constants.size ); context.pushConstants = _constants; } else { context.Verbose( GetType().Name, "No constants" ); } context.Verbose( GetType().Name, "Process Compute Program", _constants.size ); context.ProcessComputeProgram(); } } }