Added preprocessing for effects

This commit is contained in:
Simon Lübeß
2021-02-14 15:31:58 +01:00
parent 1f33949be2
commit 6ab6a6a0b9
4 changed files with 110 additions and 12 deletions
+102 -8
View File
@@ -1,10 +1,11 @@
using System;
using System.IO;
namespace GlitchyEngine.Renderer
{
public class Effect : RefCounted
{
protected GraphicsContext _context; // Todo:???
protected GraphicsContext _context ~ _?.ReleaseRef();
internal VertexShader _vs ~ _?.ReleaseRef();
internal PixelShader _ps ~ _?.ReleaseRef();
@@ -41,18 +42,24 @@ namespace GlitchyEngine.Renderer
[Obsolete("Will be removed in the future", false)]
public this()
{
}
public this(GraphicsContext context, String filename, String vsEntry, String psEntry)
{
let vs = Shader.FromFile!<VertexShader>(context, filename, vsEntry);
VertexShader = vs;
vs.ReleaseRef();
_context = context..AddRef();
CompileFromFile(filename, vsEntry, psEntry);
}
let ps = Shader.FromFile!<PixelShader>(context, filename, psEntry);
PixelShader = ps;
ps.ReleaseRef();
public this(GraphicsContext context, String filename)
{
_context = context..AddRef();
String fileContent = scope String();
String vsName = scope String();
String psName = scope String();
ProcessFile(filename, fileContent, vsName, psName);
Compile(fileContent, vsName, psName);
}
public this(String vsPath, String vsEntry, String psPath, String psEntry)
@@ -60,6 +67,93 @@ namespace GlitchyEngine.Renderer
Compile(vsPath, vsEntry, psPath, psEntry);
}
private void CompileFromFile(String filename, String vsEntry, String psEntry)
{
let vs = Shader.FromFile!<VertexShader>(_context, filename, vsEntry);
VertexShader = vs;
vs.ReleaseRef();
let ps = Shader.FromFile!<PixelShader>(_context, filename, psEntry);
PixelShader = ps;
ps.ReleaseRef();
}
private void Compile(String fileContent, String vsEntry, String psEntry)
{
// TODO: vsEntry and psEntry could be empty (which is a valid case.)
let vs = new VertexShader(_context, fileContent, vsEntry);
VertexShader = vs;
vs.ReleaseRef();
let ps = new PixelShader(_context, fileContent, psEntry);
PixelShader = ps;
ps.ReleaseRef();
}
const String effectKeyword = "#effect";
/**
* Loads the effect file and extracts the names of the vertex- and pixel-shader.
* @param filename The path of the effect file.
* @param fileContent The preprocessed effect file.
* @param vsName The string that will receive the vertex shader entry point.
* @param psName The string that will receive the pixel shader entry point.
*/
private static void ProcessFile(String filename, String fileContent, String vsName, String psName)
{
File.ReadAllText(filename, fileContent, true);
// append line ending just in case the file doesn't end with one.
fileContent.Append('\n');
int effectIndex = fileContent.IndexOf(effectKeyword, true);
Log.EngineLogger.Assert(effectIndex >= 0, "Could not find #effect preprocessor directive.");
int lineEndIndex = fileContent.IndexOf('\n', effectIndex + effectKeyword.Length);
// String containing the #effect directive
StringView effectDirective = fileContent.Substring(effectIndex, lineEndIndex - effectIndex);
int paramStartIndex = effectDirective.IndexOf('[');
Log.EngineLogger.Assert(paramStartIndex >= 0, "Expected '[' after \"#effect\"");
StringView effectToBracket = effectDirective.Substring(effectKeyword.Length, paramStartIndex - effectKeyword.Length);
// Make sure there is only whitespace between "#effect" and "["
Log.EngineLogger.Assert(effectToBracket.IsWhiteSpace, "Expected '[' after \"#effect\"");
int paramEndIndex = effectDirective.IndexOf(']');
Log.EngineLogger.Assert(paramEndIndex >= 0, "Expected ']'");
StringView parameters = effectDirective.Substring(paramStartIndex + 1, paramEndIndex - paramStartIndex - 1);
for(StringView parameter in parameters.Split(','))
{
int indexOfEquals = parameter.IndexOf("=");
Log.EngineLogger.Assert(indexOfEquals >= 0, "Expected '='");
StringView paramName = parameter.Substring(0, indexOfEquals);
paramName.Trim();
StringView paramValue = parameter.Substring(indexOfEquals + 1);
paramValue.Trim();
switch(paramName)
{
case "VS", "VertexShader":
vsName.Append(paramValue);
case "PS", "PixelShader":
psName.Append(paramValue);
default:
Log.EngineLogger.Assert(false, scope $"Unknown parameter name \"{paramName}\".");
}
}
// remove preprocessor directive from string so that the compiler wont try process it
fileContent.Remove(effectIndex, lineEndIndex - effectIndex);
}
protected extern void Compile(String vsPath, String vsEntry, String psPath, String psEntry);
}
}