Skip to content

Commit d55de20

Browse files
committed
Feature: Support output to C-style string.
1 parent 22e9918 commit d55de20

File tree

9 files changed

+109
-14
lines changed

9 files changed

+109
-14
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="COutputFormatter.cs">
3+
// Copyright (c) 2021 Dean Edis. All rights reserved.
4+
// </copyright>
5+
// <summary>
6+
// This code is provided on an "as is" basis and without warranty of any kind.
7+
// We do not warrant or make any representations regarding the use or
8+
// results of use of this code.
9+
// </summary>
10+
// -----------------------------------------------------------------------
11+
12+
using System.Linq;
13+
using System.Text;
14+
using Shrinker.Lexer;
15+
16+
namespace Shrinker.Parser
17+
{
18+
public static class COutputFormatter
19+
{
20+
public static string ToCCode(this string glsl, int originalSize, int optimizedSize)
21+
{
22+
var output = new StringBuilder();
23+
output.Append(string.Empty.WithAppMessage(originalSize, optimizedSize));
24+
output.AppendLine("static const char* fragmentShader =");
25+
26+
foreach (var line in glsl.Split('\n'))
27+
{
28+
if (string.IsNullOrWhiteSpace(line))
29+
{
30+
output.AppendLine();
31+
continue;
32+
}
33+
34+
var whitespace = new string(line.TakeWhile(char.IsWhiteSpace).ToArray());
35+
output.Append(whitespace);
36+
output.Append('\"');
37+
var s = line.Substring(whitespace.Length);
38+
39+
var leaveAlone = s.StartsWith("#") || s.StartsWith("//") || s.StartsWith("/*");
40+
41+
if (!leaveAlone)
42+
{
43+
while (s.Contains('\t'))
44+
output.Replace('\t', ' ');
45+
while (s.Contains(" "))
46+
output.Replace(" ", " ");
47+
foreach (var toSquash in new[] { "!", "#", "=", "%", "^", "&", "*", "(", ")", "-", "+", "=", ";", "{", "[", "]", "}", ":", "~", ",", "<", ">", ".", "\\", "/", "|", "?" })
48+
{
49+
foreach (var toFind in new[] { $"{toSquash} ", $" {toSquash}"})
50+
{
51+
while (s.Contains(toFind))
52+
s = s.Replace(toFind, toSquash);
53+
}
54+
}
55+
}
56+
57+
output.Append(s);
58+
59+
if (leaveAlone)
60+
output.Append("\\n");
61+
output.AppendLine("\"");
62+
}
63+
64+
output.AppendLine(";");
65+
return output.ToString();
66+
}
67+
}
68+
}

ShaderShrinker/Shrinker.Parser/OutputFormatter.cs renamed to ShaderShrinker/Shrinker.Parser/GlslOutputFormatter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// -----------------------------------------------------------------------
2-
// <copyright file="OutputFormatter.cs">
2+
// <copyright file="GlslOutputFormatter.cs">
33
// Copyright (c) 2021 Dean Edis. All rights reserved.
44
// </copyright>
55
// <summary>
@@ -20,7 +20,7 @@ namespace Shrinker.Parser
2020
/// <summary>
2121
/// Takes a syntax tree and converts it back into GLSL code for output.
2222
/// </summary>
23-
public static class OutputFormatter
23+
public static class GlslOutputFormatter
2424
{
2525
public static string ToCode(this SyntaxNode rootNode)
2626
{

ShaderShrinker/Shrinker.Parser/Shrinker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Shrinker.Parser
1717
/// <summary>
1818
/// Takes a syntax tree produced by the Parser class, and optimizes it.
1919
/// </summary>
20-
/// <remarks>The output from this stage can be passed to the OutputFormatter.</remarks>
20+
/// <remarks>The output from this stage can be passed to the GlslOutputFormatter.</remarks>
2121
public static class Shrinker
2222
{
2323
public static SyntaxNode Simplify(this SyntaxNode rootNode, CustomOptions options = null)

ShaderShrinker/Shrinker.Parser/SyntaxNodes/PragmaIfSyntaxNode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ public PragmaIfSyntaxNode(SyntaxNode startNode, SyntaxNode elseNode, SyntaxNode
3434

3535
// Read (and discard) '#if' arguments to get name.
3636
var ifName = new StringBuilder();
37-
OutputFormatter.AppendCode(ifName, startNode);
37+
GlslOutputFormatter.AppendCode(ifName, startNode);
3838

3939
var ifArgs = startNode.TakeSiblingsWhile(o => o.Token is not LineEndToken).ToList();
40-
ifArgs.ForEach(o => OutputFormatter.AppendCode(ifName, o));
40+
ifArgs.ForEach(o => GlslOutputFormatter.AppendCode(ifName, o));
4141
ifArgs.ForEach(o => o.Remove());
4242

4343
Name = ifName.ToString().Trim();

ShaderShrinker/Shrinker.Parser/SyntaxNodes/SyntaxNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ protected List<SyntaxNode> TryGetMatchingChildren(int startIndex, params Type[]
251251
.Take(types.Length)
252252
.ToList();
253253
if (samples.Count == types.Length &&
254-
samples.Where((o, i) => samples[i].GetType() == types[i] || samples[i].Token?.GetType() == types[i])
254+
samples.Where((_, i) => samples[i].GetType() == types[i] || samples[i].Token?.GetType() == types[i])
255255
.Count() == types.Length)
256256
{
257257
return samples;

ShaderShrinker/Shrinker.Parser/SyntaxNodes/SyntaxNodeExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static IEnumerable<SyntaxNode> Ancestors(this SyntaxNode node)
4646

4747
public static SyntaxNode FindLastChild(this SyntaxNode node, Func<SyntaxNode, bool> isMatchFunc) => node.FindLastChild<SyntaxNode>(isMatchFunc);
4848

49-
public static IEnumerable<SyntaxNode> TakeSiblings(this SyntaxNode node, int count) => node.TakeSiblingsWhile(o => true).Take(count);
49+
public static IEnumerable<SyntaxNode> TakeSiblings(this SyntaxNode node, int count) => node.TakeSiblingsWhile(_ => true).Take(count);
5050

5151
public static IEnumerable<SyntaxNode> TakeSiblingsWhile(this SyntaxNode node, Func<SyntaxNode, bool> isMatchFunc)
5252
{

ShaderShrinker/Shrinker.WpfApp/AppViewModel.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class AppViewModel : ViewModelBase
5252
private CustomOptions m_customOptions = CustomOptions.All();
5353
private List<FileInfo> m_presets;
5454
private readonly FileInfo m_customPreset = new FileInfo("Custom");
55+
private bool m_isOutputGlsl = true;
5556

5657
public event EventHandler<(string originalCode, string newCode)> GlslLoaded;
5758

@@ -184,6 +185,22 @@ public FileInfo SelectedPreset
184185
LoadOptionsFromPreset();
185186
}
186187
}
188+
public bool IsOutputGlsl
189+
{
190+
get => m_isOutputGlsl;
191+
set
192+
{
193+
m_isOutputGlsl = value;
194+
OnPropertyChanged();
195+
OnPropertyChanged(nameof(IsOutputC));
196+
}
197+
}
198+
199+
public bool IsOutputC
200+
{
201+
get => !IsOutputGlsl;
202+
set => IsOutputGlsl = !value;
203+
}
187204

188205
public AppViewModel()
189206
{
@@ -214,7 +231,7 @@ private void SaveGlslToClipboard(object obj)
214231
if (string.IsNullOrEmpty(glsl))
215232
return;
216233

217-
Clipboard.SetText(glsl.WithAppMessage(OriginalSize, OptimizedSize));
234+
Clipboard.SetText(GetShaderOutputText(glsl));
218235
MyMessageQueue.Enqueue("GLSL saved to clipboard");
219236
}
220237

@@ -257,12 +274,12 @@ private void SaveGlslToFile(object obj)
257274
var dialog = new SaveFileDialog
258275
{
259276
Title = "Save GLSL file",
260-
Filter = "GLSL Files|*.txt;*.glsl|All Files|*.*"
277+
Filter = "GLSL Files|*.txt;*.glsl;*.c;*.cpp;*.h;*.inl|All Files|*.*"
261278
};
262279
if (dialog.ShowDialog() != true)
263280
return;
264281

265-
File.WriteAllText(dialog.FileName, OptimizedCode.WithAppMessage(OriginalSize, OptimizedSize));
282+
File.WriteAllText(dialog.FileName, GetShaderOutputText(OptimizedCode));
266283
MyMessageQueue.Enqueue("GLSL saved to file");
267284
}
268285

@@ -357,5 +374,8 @@ public void SaveCustomOptions()
357374
Settings.Default.CustomOptions = JsonConvert.SerializeObject(CustomOptions);
358375
Settings.Default.Save();
359376
}
377+
378+
private string GetShaderOutputText(string glsl) =>
379+
IsOutputGlsl ? glsl.WithAppMessage(OriginalSize, OptimizedSize) : glsl.ToCCode(OriginalSize, OptimizedSize);
360380
}
361381
}

ShaderShrinker/Shrinker.WpfApp/MainWindow.xaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
</Button>
9494
</StackPanel>
9595

96-
<TextBlock Grid.Column="1" Text="GLSL Import" VerticalAlignment="Center">
96+
<TextBlock Grid.Column="1" Text="Shader Import" VerticalAlignment="Center">
9797
<TextBlock.LayoutTransform>
9898
<RotateTransform Angle="-90"/>
9999
</TextBlock.LayoutTransform>
@@ -147,6 +147,11 @@
147147
<StackPanel Grid.Column="0">
148148
<TextBlock Text="Step 3" FontSize="10" Margin="0,-16,0,0"/>
149149

150+
<StackPanel Margin="8,8,8,0">
151+
<RadioButton Content="GLSL" IsChecked="{Binding IsOutputGlsl}"/>
152+
<RadioButton Content="C-Style" IsChecked="{Binding IsOutputC}"/>
153+
</StackPanel>
154+
150155
<Button ToolTip="To Clipboard (CTRL+C)" Command="{Binding OnSaveToClipboardCommand}">
151156
<materialDesign:PackIcon Kind="ClipboardArrowRight"/>
152157
</Button>
@@ -161,7 +166,7 @@
161166
</materialDesign:Badged>
162167
</StackPanel>
163168

164-
<TextBlock Grid.Column="1" Text="GLSL Export" VerticalAlignment="Center">
169+
<TextBlock Grid.Column="1" Text="Shader Export" VerticalAlignment="Center">
165170
<TextBlock.LayoutTransform>
166171
<RotateTransform Angle="-90"/>
167172
</TextBlock.LayoutTransform>

ShaderShrinker/Shrinker.WpfApp/MainWindow.xaml.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
using System.Diagnostics;
1313
using System.Windows;
14+
using System.Windows.Controls;
1415
using System.Windows.Navigation;
1516

1617
namespace Shrinker.WpfApp
@@ -20,12 +21,13 @@ public partial class MainWindow
2021
public MainWindow()
2122
{
2223
InitializeComponent();
24+
ToolTipService.ShowOnDisabledProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(true));
2325

2426
var appViewModel = new AppViewModel();
2527
DataContext = appViewModel;
2628

27-
Closing += (sender, args) => appViewModel.SaveCustomOptions();
28-
appViewModel.GlslLoaded += (sender, args) =>
29+
Closing += (_, _) => appViewModel.SaveCustomOptions();
30+
appViewModel.GlslLoaded += (_, args) =>
2931
{
3032
using (new BusyCursor())
3133
{

0 commit comments

Comments
 (0)