Files
sbox-public/game/addons/tools/Code/Shaders/ShaderHooks.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

108 lines
2.5 KiB
C#

using System.Diagnostics;
using System.Threading;
namespace Editor;
internal static partial class ShaderHooks
{
[Event( "content.changed" )]
public static void OnShaderWasEdited( string filename )
{
// only respond to shaders that changed
// todo if a hlsl changed we could look at what files include it and recompile those
// that would be genuinely useful
//
// Garry: at some point in the future we could run just this, which enables dynamic
// compiling, and then it'll only recompile the shader that have changed.
//
// Or we could query the game and ask what materials are loaded and find out
// which combos are being used. Then somehow restrict the actual compile to just
// those combos. This would make iteration a ton faster. That is probably our
// best bet. That would kick ass. Lets do that. Fuck dynamic compiling.
//
// ConsoleSystem.Run( $"mat_reloadshaders {shaderName}" );
//
// Compile the shaders - in fast mode
//
CompileShader( filename.Trim( '/' ) );
}
private static ICodeEditor _editor;
private static ICodeEditor Editor
{
get
{
if ( _editor != null )
return _editor;
var editor = new CodeEditors.VisualStudioCode();
if ( editor.IsInstalled() )
{
_editor = editor;
return editor;
}
return null;
}
}
[Event( "open.shader" )]
public static void OpenShader( string filename )
{
Editor?.OpenFile( filename );
}
static CancellationTokenSource cts;
[Event( "compile.shader" )]
public static void CompileShader( string shader )
{
if ( !FileSystem.Mounted.FileExists( shader ) ) return;
if ( !shader.EndsWith( ".shader" ) ) return;
cts?.Cancel();
cts?.Dispose();
cts = new CancellationTokenSource();
_ = CompileShader( shader, cts.Token );
}
static async Task CompileShader( string file, CancellationToken token )
{
Log.Info( $"Compiling: {file}" );
var sw = Stopwatch.StartNew();
var options = new Sandbox.Engine.Shaders.ShaderCompileOptions
{
ConsoleOutput = false,
ForceRecompile = true
};
var t = await EditorUtility.CompileShader( file, options, token );
int combos = 0;
foreach ( var program in t.Programs )
{
combos += program.ComboCount;
if ( program.Output is not null )
{
foreach ( var line in program.Output )
{
Log.Warning( line );
}
}
}
if ( !t.Success )
{
Log.Warning( $"Shader compile failed after {sw.Elapsed.TotalMilliseconds:0.00}ms" );
}
else
{
Log.Info( $"Done {combos} combos in {sw.Elapsed.TotalMilliseconds:0.00}ms" );
}
}
}