diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index 781c9d15..5ee4ded3 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -200,6 +200,12 @@
+
+ True
+ True
+ Resources.resx
+
+
@@ -563,11 +569,6 @@
-
- True
- True
- Resources.resx
-
@@ -663,17 +664,9 @@
SettingsSingleFileGenerator
Settings.Designer.cs
-
-
-
-
+
-
-
-
-
-
-
+
@@ -689,21 +682,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/Source/Core/Properties/Resources.Designer.cs b/Source/Core/Properties/Resources.Designer.cs
index 38c20ac1..dacd671f 100755
--- a/Source/Core/Properties/Resources.Designer.cs
+++ b/Source/Core/Properties/Resources.Designer.cs
@@ -370,46 +370,6 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] display2d_fsaa {
- get {
- object obj = ResourceManager.GetObject("display2d_fsaa", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] display2d_fullbright {
- get {
- object obj = ResourceManager.GetObject("display2d_fullbright", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] display2d_normal {
- get {
- object obj = ResourceManager.GetObject("display2d_normal", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] display2d_vp {
- get {
- object obj = ResourceManager.GetObject("display2d_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -1070,26 +1030,6 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] plotter {
- get {
- object obj = ResourceManager.GetObject("plotter", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] plotter_vp {
- get {
- object obj = ResourceManager.GetObject("plotter_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -1580,46 +1520,6 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] things2d_fill {
- get {
- object obj = ResourceManager.GetObject("things2d_fill", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] things2d_sprite {
- get {
- object obj = ResourceManager.GetObject("things2d_sprite", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] things2d_thing {
- get {
- object obj = ResourceManager.GetObject("things2d_thing", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] things2d_vp {
- get {
- object obj = ResourceManager.GetObject("things2d_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -1810,156 +1710,6 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_constant_color {
- get {
- object obj = ResourceManager.GetObject("world3d_constant_color", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_customvertexcolor_fog_vp {
- get {
- object obj = ResourceManager.GetObject("world3d_customvertexcolor_fog_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_customvertexcolor_vp {
- get {
- object obj = ResourceManager.GetObject("world3d_customvertexcolor_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_fullbright {
- get {
- object obj = ResourceManager.GetObject("world3d_fullbright", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_fullbright_highlight {
- get {
- object obj = ResourceManager.GetObject("world3d_fullbright_highlight", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_lightpass {
- get {
- object obj = ResourceManager.GetObject("world3d_lightpass", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_lightpass_vp {
- get {
- object obj = ResourceManager.GetObject("world3d_lightpass_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_main {
- get {
- object obj = ResourceManager.GetObject("world3d_main", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_main_fog {
- get {
- object obj = ResourceManager.GetObject("world3d_main_fog", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_main_highlight {
- get {
- object obj = ResourceManager.GetObject("world3d_main_highlight", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_main_highlight_fog {
- get {
- object obj = ResourceManager.GetObject("world3d_main_highlight_fog", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_main_vp {
- get {
- object obj = ResourceManager.GetObject("world3d_main_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_skybox {
- get {
- object obj = ResourceManager.GetObject("world3d_skybox", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_skybox_vp {
- get {
- object obj = ResourceManager.GetObject("world3d_skybox_vp", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Byte[].
- ///
- internal static byte[] world3d_vertex_color {
- get {
- object obj = ResourceManager.GetObject("world3d_vertex_color", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/Source/Core/Properties/Resources.resx b/Source/Core/Properties/Resources.resx
index 48978a18..0af1b28f 100755
--- a/Source/Core/Properties/Resources.resx
+++ b/Source/Core/Properties/Resources.resx
@@ -613,81 +613,6 @@
..\Resources\Github.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\display2d.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\display2d_fsaa.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\display2d_fullbright.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\display2d_normal.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\plotter.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\plotter.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\things2d.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\things2d_fill.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\things2d_sprite.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\things2d_thing.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_constant_color.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_customvertexcolor.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_customvertexcolor_fog.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_fullbright.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_fullbright_highlight.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_lightpass.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_lightpass.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_main.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_main.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_main_fog.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_main_highlight.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_main_highlight_fog.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_skybox.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_skybox.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\world3d_vertex_color.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
..\Resources\AboutBack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
diff --git a/Source/Core/Rendering/RenderDevice.cs b/Source/Core/Rendering/RenderDevice.cs
index 800772c6..3154ae02 100755
--- a/Source/Core/Rendering/RenderDevice.cs
+++ b/Source/Core/Rendering/RenderDevice.cs
@@ -27,6 +27,7 @@ using System.Reflection;
using System.IO;
using System.Text;
using System.Linq;
+using CodeImp.DoomBuilder.Rendering.Shaders;
#endregion
@@ -66,27 +67,38 @@ namespace CodeImp.DoomBuilder.Rendering
DeclareUniform(UniformName.fogsettings, "fogsettings", UniformType.Vec4);
DeclareUniform(UniformName.fogcolor, "fogcolor", UniformType.Vec4);
- DeclareShader(ShaderName.display2d_fsaa, "display2d.vp", "display2d_fsaa.fp");
- DeclareShader(ShaderName.display2d_normal, "display2d.vp", "display2d_normal.fp");
- DeclareShader(ShaderName.display2d_fullbright, "display2d.vp", "display2d_fullbright.fp");
- DeclareShader(ShaderName.things2d_thing, "things2d.vp", "things2d_thing.fp");
- DeclareShader(ShaderName.things2d_sprite, "things2d.vp", "things2d_sprite.fp");
- DeclareShader(ShaderName.things2d_fill, "things2d.vp", "things2d_fill.fp");
- DeclareShader(ShaderName.plotter, "plotter.vp", "plotter.fp");
- DeclareShader(ShaderName.world3d_main, "world3d_main.vp", "world3d_main.fp");
- DeclareShader(ShaderName.world3d_fullbright, "world3d_main.vp", "world3d_fullbright.fp");
- DeclareShader(ShaderName.world3d_main_highlight, "world3d_main.vp", "world3d_main_highlight.fp");
- DeclareShader(ShaderName.world3d_fullbright_highlight, "world3d_main.vp", "world3d_fullbright_highlight.fp");
- DeclareShader(ShaderName.world3d_main_vertexcolor, "world3d_customvertexcolor.vp", "world3d_main.fp");
- DeclareShader(ShaderName.world3d_skybox, "world3d_skybox.vp", "world3d_skybox.fp");
- DeclareShader(ShaderName.world3d_main_highlight_vertexcolor, "world3d_customvertexcolor.vp", "world3d_main_highlight.fp");
- DeclareShader(ShaderName.world3d_main_fog, "world3d_lightpass.vp", "world3d_main_fog.fp");
- DeclareShader(ShaderName.world3d_main_highlight_fog, "world3d_lightpass.vp", "world3d_main_highlight_fog.fp");
- DeclareShader(ShaderName.world3d_main_fog_vertexcolor, "world3d_customvertexcolor_fog.vp", "world3d_main_fog.fp");
- DeclareShader(ShaderName.world3d_main_highlight_fog_vertexcolor, "world3d_customvertexcolor_fog.vp", "world3d_main_highlight_fog.fp");
- DeclareShader(ShaderName.world3d_vertex_color, "world3d_main.vp", "world3d_vertex_color.fp");
- DeclareShader(ShaderName.world3d_constant_color, "world3d_customvertexcolor.vp", "world3d_constant_color.fp");
- DeclareShader(ShaderName.world3d_lightpass, "world3d_lightpass.vp", "world3d_lightpass.fp");
+ // 2d fsaa
+ CompileShader(ShaderName.display2d_fsaa, "display2d.shader", "display2d_fsaa");
+
+ // 2d normal
+ CompileShader(ShaderName.display2d_normal, "display2d.shader", "display2d_normal");
+ CompileShader(ShaderName.display2d_fullbright, "display2d.shader", "display2d_fullbright");
+
+ // 2d things
+ CompileShader(ShaderName.things2d_thing, "things2d.shader", "things2d_thing");
+ CompileShader(ShaderName.things2d_sprite, "things2d.shader", "things2d_sprite");
+ CompileShader(ShaderName.things2d_fill, "things2d.shader", "things2d_fill");
+
+ // non-fog 3d shaders
+ CompileShader(ShaderName.world3d_main, "world3d.shader", "world3d_main");
+ CompileShader(ShaderName.world3d_fullbright, "world3d.shader", "world3d_fullbright");
+ CompileShader(ShaderName.world3d_main_highlight, "world3d.shader", "world3d_main_highlight");
+ CompileShader(ShaderName.world3d_fullbright_highlight, "world3d.shader", "world3d_fullbright_highlight");
+ CompileShader(ShaderName.world3d_vertex_color, "world3d.shader", "world3d_vertex_color");
+ CompileShader(ShaderName.world3d_main_vertexcolor, "world3d.shader", "world3d_main_vertexcolor");
+ CompileShader(ShaderName.world3d_constant_color, "world3d.shader", "world3d_constant_color");
+
+ // skybox shader
+ CompileShader(ShaderName.world3d_skybox, "world3d_skybox.shader", "world3d_skybox");
+
+ // fog 3d shaders
+ CompileShader(ShaderName.world3d_main_fog, "world3d.shader", "world3d_main_fog");
+ CompileShader(ShaderName.world3d_main_highlight_fog, "world3d.shader", "world3d_main_highlight_fog");
+ CompileShader(ShaderName.world3d_main_fog_vertexcolor, "world3d.shader", "world3d_main_fog_vertexcolor");
+ CompileShader(ShaderName.world3d_main_highlight_fog_vertexcolor, "world3d.shader", "world3d_main_highlight_fog_vertexcolor");
+
+ // pure light shader
+ CompileShader(ShaderName.world3d_lightpass, "world3d.shader", "world3d_lightpass");
SetupSettings();
}
@@ -139,6 +151,26 @@ namespace CodeImp.DoomBuilder.Rendering
RenderDevice_DeclareShader(Handle, name, name.ToString(), GetResourceText(vertResourceName), GetResourceText(fragResourceName));
}
+ // save precompiled shaders -- don't build from scratch every time
+ private static Dictionary precompiledGroups = new Dictionary();
+ public void CompileShader(ShaderName internalName, string groupName, string shaderName)
+ {
+ ShaderGroup sg;
+
+ if (precompiledGroups.ContainsKey(groupName))
+ sg = precompiledGroups[groupName];
+ else sg = ShaderCompiler.Compile(GetResourceText(groupName));
+
+ Shader s = sg.GetShader(shaderName);
+
+ if (s == null)
+ throw new RenderDeviceException(string.Format("Shader {0}::{1} not found", groupName, shaderName));
+
+ General.WriteLogLine(string.Format("===========================================\nDBG: loading shader {0} / {1}\n\nVertex source: {2}\n\nFragment source: {3}\n\n===========================================",
+ groupName, shaderName, s.GetVertexSource(), s.GetFragmentSource()));
+ RenderDevice_DeclareShader(Handle, internalName, internalName.ToString(), s.GetVertexSource(), s.GetFragmentSource());
+ }
+
static string GetResourceText(string name)
{
string fullname = string.Format("CodeImp.DoomBuilder.Resources.{0}", name);
@@ -617,7 +649,6 @@ namespace CodeImp.DoomBuilder.Rendering
things2d_thing,
things2d_sprite,
things2d_fill,
- plotter,
world3d_main,
world3d_fullbright,
world3d_main_highlight,
diff --git a/Source/Core/Rendering/Shaders/ShaderCompiler.cs b/Source/Core/Rendering/Shaders/ShaderCompiler.cs
new file mode 100755
index 00000000..e1c5c3a5
--- /dev/null
+++ b/Source/Core/Rendering/Shaders/ShaderCompiler.cs
@@ -0,0 +1,853 @@
+using CodeImp.DoomBuilder.ZDoom;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CodeImp.DoomBuilder.Rendering.Shaders
+{
+ internal class ShaderField
+ {
+ public int Line;
+ public List> ArrayDimensions;
+ public string TypeName;
+ public List Initializer;
+ public string Name;
+ }
+
+ internal class ShaderFunction
+ {
+ public int Line;
+ public int CodeLine;
+ public string ReturnValue;
+ public string Name;
+ public List Arguments;
+ public List Code;
+ }
+
+ class Shader
+ {
+ private ShaderGroup Group;
+ internal string ParentName;
+ public int CodeLine;
+ public string Name;
+ // data input for vertex shader
+ public List In;
+ // data between vertex and fragment shader
+ public List V2F;
+ // data output for fragment shader
+ public List Out;
+ // source for main() of vertex shader
+ public int SourceVertexLine;
+ public List SourceVertex;
+ // source for main() of fragment shader
+ public int SourceFragmentLine;
+ public List SourceFragment;
+
+ private const string GLSLInternalSeparator = "_";
+
+ public Shader(ShaderGroup group)
+ {
+ Group = group;
+ }
+
+ // dumps all uniforms into a string
+ private string GetTokenListSource(List tokens)
+ {
+ string ss = "";
+ foreach (ZScriptToken tok in tokens)
+ {
+ bool isBlock = false;
+ switch (tok.Type)
+ {
+ case ZScriptTokenType.LineComment:
+ ss += "//";
+ break;
+ case ZScriptTokenType.BlockComment:
+ ss += "/*";
+ isBlock = true;
+ break;
+ }
+ ss += tok.Value;
+ if (isBlock) ss += "*/";
+ }
+ return ss;
+ }
+
+ private string GetUniformSource()
+ {
+
+ string output = "";
+ foreach (ShaderField field in Group.Uniforms)
+ {
+
+ output += string.Format("#line {0}\n", field.Line);
+
+ output += "uniform ";
+ output += field.TypeName;
+
+ if (field.ArrayDimensions != null)
+ {
+ foreach (List arrayDim in field.ArrayDimensions)
+ output += "[" + GetTokenListSource(arrayDim) + "]";
+ }
+
+ output += " " + field.Name;
+
+ if (field.Initializer != null)
+ output += GetTokenListSource(field.Initializer);
+
+ output += ";\n";
+
+ }
+
+ return output;
+
+ }
+
+ private string GetDataIOInternalName(string block, string name)
+ {
+ return string.Format("{2}SC{2}B{0}{2}F{1}", block, name, GLSLInternalSeparator);
+ }
+
+ private string GetDataIOSource(string prefix, string blockid, List block, bool vertexInput)
+ {
+
+ string output = "";
+ foreach (ShaderField field in block)
+ {
+
+ output += string.Format("#line {0}\n", field.Line);
+
+ if (vertexInput)
+ {
+ int location;
+ switch (field.Name)
+ {
+ case "Position":
+ location = 0;
+ break;
+ case "Color":
+ location = 1;
+ break;
+ case "TextureCoordinate":
+ location = 2;
+ break;
+ case "Normal":
+ location = 3;
+ break;
+ default:
+ throw new ShaderCompileException("Invalid input field {0} (not supported)", field.Name);
+ }
+
+ output += string.Format("layout(location = {0}) ", location);
+ }
+
+ output += prefix + " ";
+ output += field.TypeName;
+
+ if (field.ArrayDimensions != null)
+ {
+ foreach (List arrayDim in field.ArrayDimensions)
+ output += "[" + GetTokenListSource(arrayDim) + "]";
+ }
+
+ output += " " + GetDataIOInternalName(blockid, field.Name);
+
+ if (field.Initializer != null)
+ output += GetTokenListSource(field.Initializer);
+
+ output += ";\n";
+
+ }
+
+ return output;
+
+ }
+
+ private void GetReferencedFunctions(List source, List functions)
+ {
+
+ for (int i = 0; i < source.Count; i++)
+ {
+
+ ZScriptToken token = source[i];
+ if (token.Type != ZScriptTokenType.Identifier)
+ continue;
+
+ if (functions.Contains(token.Value))
+ continue;
+
+ // check token to the left - needs to not be identifier.
+ // check token to the right - needs to be open parenthesis
+ // ---
+ // the idea is that we can differentiate pixel = desaturate(...) from vec4 desaturate(1,1,1,1)
+ //
+ ZScriptTokenType leftToken = ZScriptTokenType.Invalid;
+ ZScriptTokenType rightToken = ZScriptTokenType.Invalid;
+
+ for (int j = i-1; j >= 0; j--)
+ {
+ ZScriptTokenType tt = source[j].Type;
+ if (!IsWhitespace(tt))
+ {
+ leftToken = tt;
+ break;
+ }
+ }
+
+ for (int j = i+1; j < source.Count; j++)
+ {
+ ZScriptTokenType tt = source[j].Type;
+ if (!IsWhitespace(tt))
+ {
+ rightToken = tt;
+ break;
+ }
+ }
+
+ if (leftToken != ZScriptTokenType.Identifier && rightToken == ZScriptTokenType.OpenParen)
+ {
+
+ // find function
+ functions.Add(token.Value);
+ // if function was found, recurse and find functions it may depend on.
+ ShaderFunction func = Group.GetFunction(token.Value);
+ if (func != null)
+ GetReferencedFunctions(func.Code, functions);
+
+ }
+
+ }
+
+ }
+
+ private string GetFunctionSource(List shaderSource)
+ {
+
+ List functionNames = new List();
+ GetReferencedFunctions(shaderSource, functionNames);
+
+ string preOutput = "";
+ string output = "";
+
+ foreach (string functionName in functionNames)
+ {
+ ShaderFunction func = Group.GetFunction(functionName);
+ if (func == null)
+ continue;
+
+ string funcOutput = string.Format("#line {0}\n", func.Line) + func.ReturnValue + " " + func.Name + " (" + GetTokenListSource(func.Arguments) + ")";
+ preOutput += funcOutput + ";\n";
+
+ funcOutput += " {\n" + string.Format("#line {0}\n", func.CodeLine) +GetTokenListSource(func.Code) + "}\n";
+ output += funcOutput;
+
+ }
+
+ return preOutput + "\n" + output;
+
+ }
+
+ private static bool IsWhitespace(ZScriptTokenType t)
+ {
+ switch (t)
+ {
+ case ZScriptTokenType.Whitespace:
+ case ZScriptTokenType.LineComment:
+ case ZScriptTokenType.BlockComment:
+ case ZScriptTokenType.Newline:
+ return true;
+ }
+ return false;
+ }
+
+ public List ReplaceIO(List tokens)
+ {
+
+ List output = new List(tokens);
+
+ // we replace all . with GetDataBlockInternalName(, )
+ // thus, "in" and "out" are reserved keywords and may not be found out of such context
+ for (int i = 0; i < output.Count; i++)
+ {
+
+ ZScriptToken token = output[i];
+ if (token.Type != ZScriptTokenType.Identifier)
+ continue;
+ if (token.Value != "in" && token.Value != "out" && token.Value != "v2f")
+ continue;
+
+ string structPrefix = token.Value;
+
+ int startIndex = i;
+
+ i++;
+ // skip whitespace...
+ for (; i < output.Count; i++)
+ if (!IsWhitespace(output[i].Type)) break;
+
+ if (i >= output.Count || output[i].Type != ZScriptTokenType.Dot)
+ continue;
+
+ i++;
+ // skip whitespace again...
+ for (; i < output.Count; i++)
+ if (!IsWhitespace(output[i].Type)) break;
+
+ if (i >= output.Count || output[i].Type != ZScriptTokenType.Identifier)
+ continue;
+
+ //
+ string fieldName = output[i].Value;
+ string realName = GetDataIOInternalName(structPrefix, fieldName);
+ // now, remove all tokens between prefix and current
+ output.RemoveRange(startIndex + 1, i - startIndex);
+ ZScriptToken realToken = new ZScriptToken(output[startIndex]);
+ realToken.Value = realName;
+ output[startIndex] = realToken;
+ i = startIndex - 1;
+
+ // check if this field exists, just in case. and produce an error
+ List searchIn = null;
+ switch (structPrefix)
+ {
+ case "in":
+ searchIn = In;
+ break;
+ case "out":
+ searchIn = Out;
+ break;
+ case "v2f":
+ searchIn = V2F;
+ break;
+ }
+ if (searchIn != null)
+ {
+ bool found = false;
+ foreach (ShaderField field in searchIn)
+ {
+ if (field.Name == fieldName)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ throw new ShaderCompileException("Referenced non-existent {0} field {1}", structPrefix, fieldName);
+ }
+
+ }
+
+ return output;
+
+ }
+
+ public string GetVertexSource()
+ {
+ if (In == null || V2F == null || SourceVertex == null)
+ throw new ShaderCompileException("Tried to compile incomplete shader {0}", Name);
+
+ string src = "";
+ src += GetDataIOSource("in", "in", In, true) + "\n\n";
+ src += GetDataIOSource("out", "v2f", V2F, false) + "\n\n";
+ src += GetUniformSource() + "\n";
+ src += GetFunctionSource(SourceVertex) + "\n\n";
+ src += "void main() {\n" + string.Format("#line {0}\n", SourceVertexLine) + GetTokenListSource(ReplaceIO(SourceVertex)) + "\n}\n\n";
+
+ return src;
+ }
+
+ public string GetFragmentSource()
+ {
+ if (Out == null || V2F == null || SourceFragment == null)
+ throw new ShaderCompileException("Tried to compile incomplete shader {0}", Name);
+
+ string src = "";
+ src += GetDataIOSource("in", "v2f", V2F, false) + "\n\n";
+ src += GetDataIOSource("out", "out", Out, false) + "\n\n";
+ src += GetUniformSource() + "\n";
+ src += GetFunctionSource(SourceFragment) + "\n\n";
+ src += "void main() {\n" + string.Format("#line {0}\n", SourceFragmentLine) + GetTokenListSource(ReplaceIO(SourceFragment)) + "\n}\n\n";
+
+ return src;
+ }
+ }
+
+ class ShaderGroup
+ {
+ internal List Uniforms = new List();
+ internal List Shaders = new List();
+ internal List Functions = new List();
+
+ public Shader GetShader(string identifier)
+ {
+ foreach (Shader s in Shaders)
+ if (s.Name == identifier) return s;
+ return null;
+ }
+
+ public ShaderFunction GetFunction(string identifier)
+ {
+ foreach (ShaderFunction f in Functions)
+ if (f.Name == identifier) return f;
+ return null;
+ }
+ }
+
+ class ShaderCompileException : Exception
+ {
+ public ShaderCompileException(string fmt, params object[] v) : base(string.Format(fmt, v)) { }
+ }
+
+ class ShaderCompiler
+ {
+ // this is to implement partial parsing. it counts {}, (), and []. it stops parsing at the specified type, if outside of nesting.
+ // also if last block token equals to the type, it will stop at the outer level. (i.e. last })
+ private static List ReadEverythingUntil(ZScriptTokenizer t, ZScriptTokenType type, bool eofIsOk, bool skipWhitespace)
+ {
+ List tokens = new List();
+
+ int levelCurly = 0;
+ int levelSquare = 0;
+ int levelParen = 0;
+
+ while (true)
+ {
+ if (skipWhitespace)
+ t.SkipWhitespace();
+
+ long cpos = t.Reader.BaseStream.Position;
+
+ ZScriptToken token = t.ReadToken();
+ if (token == null)
+ {
+ if (!eofIsOk)
+ throw new ShaderCompileException("Expected {0} or token, got ", type);
+ break;
+ }
+
+ // if this is the end token, don't check anything -- just return
+ if (levelCurly == 0 && levelSquare == 0 && levelParen == 0 && token.Type == type)
+ {
+ // rewind and return token list
+ t.Reader.BaseStream.Position = cpos;
+ break;
+ }
+
+ switch (token.Type)
+ {
+ case ZScriptTokenType.OpenCurly:
+ levelCurly++;
+ break;
+ case ZScriptTokenType.CloseCurly:
+ levelCurly--;
+ break;
+ case ZScriptTokenType.OpenParen:
+ levelParen++;
+ break;
+ case ZScriptTokenType.CloseParen:
+ levelParen--;
+ break;
+ case ZScriptTokenType.OpenSquare:
+ levelSquare++;
+ break;
+ case ZScriptTokenType.CloseSquare:
+ levelSquare--;
+ break;
+ }
+
+ tokens.Add(token);
+
+ }
+
+ return tokens;
+ }
+
+ private static void CompileShaderField(ShaderField field, ZScriptTokenizer t)
+ {
+
+ ZScriptToken token;
+ // read name and array dimensions
+ while (true)
+ {
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.OpenSquare, ZScriptTokenType.Identifier);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected array dimensions or field name, got {0}", token?.ToString() ?? "");
+
+ // array finished
+ if (token.Type == ZScriptTokenType.Identifier)
+ {
+ field.Name = token.Value;
+ break;
+ }
+
+ // read array
+ List arrayDimTokens = ReadEverythingUntil(t, ZScriptTokenType.CloseSquare, false, false);
+ if (field.ArrayDimensions == null)
+ field.ArrayDimensions = new List>();
+ field.ArrayDimensions.Add(arrayDimTokens);
+
+ token = t.ExpectToken(ZScriptTokenType.CloseSquare);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected closing square brace, got {0}", token?.ToString() ?? "");
+ }
+
+ // read additional array dimensions if present, and initializer. or end parsing
+ while (true)
+ {
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.OpenSquare, ZScriptTokenType.OpAssign, ZScriptTokenType.Semicolon);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected array dimensions, initializer or semicolon, got {0}", token?.ToString() ?? "");
+
+ // field is done
+ if (token.Type == ZScriptTokenType.Semicolon)
+ break;
+
+ // has initializer
+ if (token.Type == ZScriptTokenType.OpAssign)
+ {
+ field.Initializer = ReadEverythingUntil(t, ZScriptTokenType.Semicolon, false, false);
+ token = t.ExpectToken(ZScriptTokenType.Semicolon);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected semicolon, got {0}", token?.ToString() ?? "");
+ break;
+ }
+
+ // read array
+ List arrayDimTokens = ReadEverythingUntil(t, ZScriptTokenType.CloseSquare, false, false);
+ if (field.ArrayDimensions == null)
+ field.ArrayDimensions = new List>();
+ field.ArrayDimensions.Add(arrayDimTokens);
+
+ token = t.ExpectToken(ZScriptTokenType.CloseSquare);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected closing square brace, got {0}", token?.ToString() ?? "");
+ }
+
+ }
+
+ private static void CompileUniforms(ShaderGroup output, ZScriptTokenizer t)
+ {
+
+ // so a type of a variable is normally identifier+array dimensions
+ // array dimensions may also exist on the variable itself (oh god this shitty C syntax)
+ t.SkipWhitespace();
+ ZScriptToken token;
+
+ token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected uniforms block, got {0}", token?.ToString() ?? "");
+
+ while (true)
+ {
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected uniform or end of block, got {0}", token?.ToString() ?? "");
+
+ if (token.Type == ZScriptTokenType.CloseCurly)
+ break; // done reading uniforms
+
+ // first goes the name, then array dimensions, then the variable name, then array dimensions, then initializer
+ ShaderField field = new ShaderField();
+ field.Line = t.PositionToLine(token.Position);
+ field.TypeName = token.Value;
+
+ CompileShaderField(field, t);
+
+ // done reading field, add it
+ output.Uniforms.Add(field);
+
+ }
+
+ }
+
+ private static void CompileFunctions(ShaderGroup output, ZScriptTokenizer t)
+ {
+
+ // so a type of a variable is normally identifier+array dimensions
+ // array dimensions may also exist on the variable itself (oh god this shitty C syntax)
+ t.SkipWhitespace();
+ ZScriptToken token;
+
+ token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected functions block, got {0}", token?.ToString() ?? "");
+
+ while (true)
+ {
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected function or end of block, got {0}", token?.ToString() ?? "");
+
+ if (token.Type == ZScriptTokenType.CloseCurly)
+ break; // done reading functions
+
+ // () { }
+ ShaderFunction func = new ShaderFunction();
+ func.Line = t.PositionToLine(token.Position);
+ func.ReturnValue = token.Value;
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected function name, got {0}", token?.ToString() ?? "");
+
+ func.Name = token.Value;
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.OpenParen);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected function argument list, got {0}", token?.ToString() ?? "");
+
+ func.Arguments = ReadEverythingUntil(t, ZScriptTokenType.CloseParen, false, false);
+
+ token = t.ExpectToken(ZScriptTokenType.CloseParen);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected end of function arguments, got {0}", token?.ToString() ?? "");
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected function code block, got {0}", token?.ToString() ?? "");
+
+ func.CodeLine = t.PositionToLine(token.Position);
+ func.Code = ReadEverythingUntil(t, ZScriptTokenType.CloseCurly, false, false);
+
+ token = t.ExpectToken(ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected end of function code block, got {0}", token?.ToString() ?? "");
+
+ output.Functions.Add(func);
+
+ }
+
+ }
+
+ private static List CompileShaderDataBlock(ZScriptTokenizer t)
+ {
+
+ List fields = new List();
+
+ t.SkipWhitespace();
+ ZScriptToken token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected data block, got {0}", token?.ToString() ?? "");
+
+ while (true)
+ {
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected data field or end of block, got {0}", token?.ToString() ?? "");
+
+ if (token.Type == ZScriptTokenType.CloseCurly)
+ break;
+
+ ShaderField field = new ShaderField();
+ field.Line = t.PositionToLine(token.Position);
+ field.TypeName = token.Value;
+
+ CompileShaderField(field, t);
+
+ fields.Add(field);
+
+ }
+
+ return fields;
+
+ }
+
+ private static List CompileShaderSource(ZScriptTokenizer t)
+ {
+
+ // syntax:
+ // fragment { ... code ... }
+ // or
+ // vertex { ... code ... }
+
+ t.SkipWhitespace();
+ ZScriptToken token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected shader source block, got {0}", token?.ToString() ?? "");
+
+ List tokens = ReadEverythingUntil(t, ZScriptTokenType.CloseCurly, false, false);
+
+ token = t.ExpectToken(ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected end of shader source block, got {0}", token?.ToString() ?? "");
+
+ return tokens;
+
+ }
+
+ private static void CompileShader(ShaderGroup output, ZScriptTokenizer t)
+ {
+
+ t.SkipWhitespace();
+
+ ZScriptToken token = t.ExpectToken(ZScriptTokenType.Identifier);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected shader identifier, got {0}", token?.ToString() ?? "");
+
+ t.SkipWhitespace();
+
+ Shader s = new Shader(output);
+ s.Name = token.Value;
+ output.Shaders.Add(s);
+
+ token = t.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected parent identifier or shader block, got {0}", token?.ToString() ?? "");
+
+ // has parent shader id
+ if (token.Type == ZScriptTokenType.Identifier)
+ {
+
+ if (token.Value != "extends")
+ throw new ShaderCompileException("Expected 'extends', got {0}", token.ToString());
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected parent identifier, got {0}", token?.ToString() ?? "");
+
+ s.ParentName = token.Value;
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.OpenCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected shader block, got {0}", token?.ToString() ?? "");
+
+ }
+
+
+ s.CodeLine = t.PositionToLine(token.Position);
+
+ while (true)
+ {
+
+ t.SkipWhitespace();
+ token = t.ExpectToken(ZScriptTokenType.Identifier, ZScriptTokenType.CloseCurly);
+ if (!(token?.IsValid ?? true))
+ throw new ShaderCompileException("Expected shader sub-block or end of block, got {0}", token?.ToString() ?? "");
+
+ if (token.Type == ZScriptTokenType.CloseCurly)
+ break;
+
+ switch (token.Value)
+ {
+ case "in":
+ s.In = CompileShaderDataBlock(t);
+ break;
+ case "out":
+ s.Out = CompileShaderDataBlock(t);
+ break;
+ case "v2f":
+ s.V2F = CompileShaderDataBlock(t);
+ break;
+ case "vertex":
+ s.SourceVertex = CompileShaderSource(t);
+ if (s.SourceVertex != null && s.SourceVertex.Count > 0)
+ s.SourceVertexLine = t.PositionToLine(s.SourceVertex[0].Position);
+ break;
+ case "fragment":
+ s.SourceFragment = CompileShaderSource(t);
+ if (s.SourceFragment != null && s.SourceFragment.Count > 0)
+ s.SourceFragmentLine = t.PositionToLine(s.SourceFragment[0].Position);
+ break;
+ default:
+ throw new ShaderCompileException("Expected shader sub-block, got {0}", token.ToString());
+ }
+
+ }
+
+ }
+
+ public static ShaderGroup Compile(string src)
+ {
+ ShaderGroup output = new ShaderGroup();
+
+ using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(src)))
+ using (BinaryReader br = new BinaryReader(ms))
+ {
+ ZScriptTokenizer t = new ZScriptTokenizer(br);
+
+ // main cycle
+ // in the root scope, we allow three blocks:
+ // - uniforms{}
+ // - functions{}
+ // - shader {}
+ // everything else is a syntax error.
+ while (true)
+ {
+ t.SkipWhitespace();
+ ZScriptToken token = t.ExpectToken(ZScriptTokenType.Identifier);
+ if (token == null)
+ break;
+
+ if (!token.IsValid)
+ throw new ShaderCompileException("Expected 'uniforms', 'functions', or 'shader'; got {0}", token.ToString());
+
+ switch (token.Value)
+ {
+ case "uniforms":
+ CompileUniforms(output, t);
+ break;
+ case "functions":
+ CompileFunctions(output, t);
+ break;
+ case "shader":
+ CompileShader(output, t);
+ break;
+ default:
+ throw new ShaderCompileException("Expected 'uniforms', 'functions', or 'shader'; got {0}", token.ToString());
+ }
+ }
+
+ // done parsing, postprocess - apply parents
+ foreach (Shader s in output.Shaders)
+ {
+ List parents = new List();
+ parents.Add(s.Name);
+ Shader p = s;
+ while (p.ParentName != null && p.ParentName != "")
+ {
+ string parentName = p.ParentName;
+ if (parents.Contains(parentName))
+ throw new ShaderCompileException("Recursive parent shader {0} found", parentName);
+ parents.Add(parentName);
+ p = output.GetShader(parentName);
+ if (p == null)
+ throw new ShaderCompileException("Parent shader {0} not found", parentName);
+
+ if (s.In == null) s.In = p.In;
+ if (s.Out == null) s.Out = p.Out;
+ if (s.V2F == null) s.V2F = p.V2F;
+ if (s.SourceFragment == null)
+ {
+ s.SourceFragment = p.SourceFragment;
+ s.SourceFragmentLine = p.SourceFragmentLine;
+ }
+ if (s.SourceVertex == null)
+ {
+ s.SourceVertex = p.SourceVertex;
+ s.SourceVertexLine = p.SourceVertexLine;
+ }
+ }
+ }
+
+ return output;
+ }
+ }
+ }
+}
diff --git a/Source/Core/Resources/display2d.shader b/Source/Core/Resources/display2d.shader
new file mode 100755
index 00000000..8acf625b
--- /dev/null
+++ b/Source/Core/Resources/display2d.shader
@@ -0,0 +1,118 @@
+uniforms
+{
+ mat4 projection;
+
+ // Render settings
+ // x = texel width
+ // y = texel height
+ // z = FSAA blend factor
+ // w = transparency
+ vec4 rendersettings;
+ float desaturation;
+
+ sampler2D texture1;
+ vec4 texturefactor;
+}
+
+functions
+{
+ vec3 desaturate(vec3 texel)
+ {
+ float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
+ return mix(texel, vec3(gray), desaturation);
+ }
+
+ // This blends the max of 2 pixels
+ vec4 addcolor(vec4 c1, vec4 c2)
+ {
+ return vec4(
+ max(c1.r, c2.r),
+ max(c1.g, c2.g),
+ max(c1.b, c2.b),
+ clamp(c1.a + c2.a * 0.5, 0.0, 1.0));
+ }
+}
+
+shader display2d_normal
+{
+ in
+ {
+ vec3 Position;
+ vec4 Color;
+ vec2 TextureCoordinate;
+ }
+
+ v2f
+ {
+ vec4 Color;
+ vec2 UV;
+ }
+
+ out
+ {
+ vec4 FragColor;
+ }
+
+ vertex
+ {
+ gl_Position = projection * vec4(in.Position, 1.0);
+ v2f.Color = in.Color;
+ v2f.UV = in.TextureCoordinate;
+ }
+
+ fragment
+ {
+ vec4 c = texture(texture1, v2f.UV);
+ out.FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * v2f.Color;
+ out.FragColor *= texturefactor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
+
+shader display2d_fullbright extends display2d_normal
+{
+ fragment
+ {
+ vec4 c = texture(texture1, v2f.UV);
+ out.FragColor = vec4(c.rgb, c.a * rendersettings.w);
+ out.FragColor *= texturefactor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
+
+shader display2d_fsaa extends display2d_normal
+{
+ fragment
+ {
+ vec4 c = texture(texture1, v2f.UV);
+
+ // If this pixel is not drawn on...
+ if(c.a < 0.1)
+ {
+ // Mix the colors of nearby pixels
+ vec4 n = vec4(0.0);
+ n = addcolor(n, texture(texture1, vec2(v2f.UV.x + rendersettings.x, v2f.UV.y)));
+ n = addcolor(n, texture(texture1, vec2(v2f.UV.x - rendersettings.x, v2f.UV.y)));
+ n = addcolor(n, texture(texture1, vec2(v2f.UV.x, v2f.UV.y + rendersettings.y)));
+ n = addcolor(n, texture(texture1, vec2(v2f.UV.x, v2f.UV.y - rendersettings.y)));
+
+ out.FragColor = vec4(desaturate(n.rgb), n.a * rendersettings.z * rendersettings.w);
+ }
+ else
+ {
+ out.FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * v2f.Color;
+ }
+
+ out.FragColor *= texturefactor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
\ No newline at end of file
diff --git a/Source/Core/Resources/display2d.vp b/Source/Core/Resources/display2d.vp
deleted file mode 100644
index 4d00806c..00000000
--- a/Source/Core/Resources/display2d.vp
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-
-out vec4 Color;
-out vec2 UV;
-
-uniform mat4 projection;
-
-void main()
-{
- gl_Position = projection * vec4(AttrPosition, 1.0);
- Color = AttrColor;
- UV = AttrUV;
-}
diff --git a/Source/Core/Resources/display2d_fsaa.fp b/Source/Core/Resources/display2d_fsaa.fp
deleted file mode 100644
index 59cec51b..00000000
--- a/Source/Core/Resources/display2d_fsaa.fp
+++ /dev/null
@@ -1,60 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-// Render settings
-// x = texel width
-// y = texel height
-// z = FSAA blend factor
-// w = transparency
-uniform vec4 rendersettings;
-uniform float desaturation;
-
-uniform sampler2D texture1;
-uniform vec4 texturefactor;
-
-// This blends the max of 2 pixels
-vec4 addcolor(vec4 c1, vec4 c2)
-{
- return vec4(
- max(c1.r, c2.r),
- max(c1.g, c2.g),
- max(c1.b, c2.b),
- clamp(c1.a + c2.a * 0.5, 0.0, 1.0));
-}
-
-vec3 desaturate(vec3 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return mix(texel, vec3(gray), desaturation);
-}
-
-void main()
-{
- vec4 c = texture(texture1, UV);
-
- // If this pixel is not drawn on...
- if(c.a < 0.1)
- {
- // Mix the colors of nearby pixels
- vec4 n = vec4(0.0);
- n = addcolor(n, texture(texture1, vec2(UV.x + rendersettings.x, UV.y)));
- n = addcolor(n, texture(texture1, vec2(UV.x - rendersettings.x, UV.y)));
- n = addcolor(n, texture(texture1, vec2(UV.x, UV.y + rendersettings.y)));
- n = addcolor(n, texture(texture1, vec2(UV.x, UV.y - rendersettings.y)));
-
- FragColor = vec4(desaturate(n.rgb), n.a * rendersettings.z * rendersettings.w);
- }
- else
- {
- FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * Color;
- }
-
- FragColor *= texturefactor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/display2d_fullbright.fp b/Source/Core/Resources/display2d_fullbright.fp
deleted file mode 100644
index c6d973b1..00000000
--- a/Source/Core/Resources/display2d_fullbright.fp
+++ /dev/null
@@ -1,26 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-// Render settings
-// x = texel width
-// y = texel height
-// z = FSAA blend factor
-// w = transparency
-uniform vec4 rendersettings;
-
-uniform sampler2D texture1;
-uniform vec4 texturefactor;
-
-void main()
-{
- vec4 c = texture(texture1, UV);
- FragColor = vec4(c.rgb, c.a * rendersettings.w);
- FragColor *= texturefactor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/display2d_normal.fp b/Source/Core/Resources/display2d_normal.fp
deleted file mode 100644
index a58cb381..00000000
--- a/Source/Core/Resources/display2d_normal.fp
+++ /dev/null
@@ -1,33 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-// Render settings
-// x = texel width
-// y = texel height
-// z = FSAA blend factor
-// w = transparency
-uniform vec4 rendersettings;
-uniform float desaturation;
-
-uniform sampler2D texture1;
-uniform vec4 texturefactor;
-
-vec3 desaturate(vec3 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return mix(texel, vec3(gray), desaturation);
-}
-
-void main()
-{
- vec4 c = texture(texture1, UV);
- FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * Color;
- FragColor *= texturefactor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/plotter.fp b/Source/Core/Resources/plotter.fp
deleted file mode 100644
index e0fff0cc..00000000
--- a/Source/Core/Resources/plotter.fp
+++ /dev/null
@@ -1,20 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-void main()
-{
- // line stipple
- if (mod(UV.x, 2.0) > 1.0)
- discard;
-
- // line smoothing
- float linewidth = 3.0;
- float falloff = 1.8; //1.5..2.5
- float centerdist = abs(UV.y);
- float a = pow(clamp((linewidth - centerdist) / linewidth, 0.0, 1.0), falloff);
-
- FragColor = vec4(Color.rgb, Color.a * a);
-}
diff --git a/Source/Core/Resources/plotter.vp b/Source/Core/Resources/plotter.vp
deleted file mode 100644
index 478e82eb..00000000
--- a/Source/Core/Resources/plotter.vp
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-
-out vec4 Color;
-out vec2 UV;
-
-uniform mat4 projection;
-
-void main()
-{
- gl_Position = projection * vec4(AttrPosition, 1.0f);
- Color = AttrColor;
- UV = AttrUV;
-}
diff --git a/Source/Core/Resources/things2d.shader b/Source/Core/Resources/things2d.shader
new file mode 100755
index 00000000..f94ea9bc
--- /dev/null
+++ b/Source/Core/Resources/things2d.shader
@@ -0,0 +1,105 @@
+uniforms
+{
+ mat4 projection;
+
+ // Render settings
+ // w = transparency
+ vec4 rendersettings;
+ float desaturation;
+
+ sampler2D texture1;
+ vec4 texturefactor;
+
+ vec4 fillColor;
+}
+
+functions
+{
+ vec3 desaturate(vec3 texel)
+ {
+ float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
+ return mix(texel, vec3(gray), desaturation);
+ }
+}
+
+shader things2d
+{
+ in
+ {
+ vec3 Position;
+ vec4 Color;
+ vec2 TextureCoordinate;
+ }
+
+ v2f
+ {
+ vec4 Color;
+ vec2 UV;
+ }
+
+ out
+ {
+ vec4 FragColor;
+ }
+
+ vertex
+ {
+ gl_Position = projection * vec4(in.Position, 1.0);
+ v2f.Color = in.Color;
+ v2f.UV = in.TextureCoordinate;
+ }
+}
+
+shader things2d_fill extends things2d
+{
+ fragment
+ {
+ out.FragColor = fillColor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
+
+shader things2d_thing extends things2d
+{
+ fragment
+ {
+ vec4 c = texture(texture1, v2f.UV);
+ out.FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * v2f.Color;
+
+ out.FragColor *= texturefactor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
+
+shader things2d_sprite extends things2d
+{
+ fragment
+ {
+ // Take this pixel's color
+ vec4 c = texture(texture1, v2f.UV);
+
+ // Modulate it by selection color
+ if (v2f.Color.a > 0.0)
+ {
+ vec3 cr = desaturate(c.rgb);
+ out.FragColor = vec4((cr.r + v2f.Color.r) / 2.0, (cr.g + v2f.Color.g) / 2.0, (cr.b + v2f.Color.b) / 2.0, c.a * rendersettings.w * v2f.Color.a);
+ }
+ else
+ {
+ // Or leave it as it is
+ out.FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w);
+ }
+
+ out.FragColor *= texturefactor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
\ No newline at end of file
diff --git a/Source/Core/Resources/things2d.vp b/Source/Core/Resources/things2d.vp
deleted file mode 100644
index 4d00806c..00000000
--- a/Source/Core/Resources/things2d.vp
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-
-out vec4 Color;
-out vec2 UV;
-
-uniform mat4 projection;
-
-void main()
-{
- gl_Position = projection * vec4(AttrPosition, 1.0);
- Color = AttrColor;
- UV = AttrUV;
-}
diff --git a/Source/Core/Resources/things2d_fill.fp b/Source/Core/Resources/things2d_fill.fp
deleted file mode 100644
index 8f984384..00000000
--- a/Source/Core/Resources/things2d_fill.fp
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-uniform vec4 fillColor;
-
-void main()
-{
- FragColor = fillColor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/things2d_sprite.fp b/Source/Core/Resources/things2d_sprite.fp
deleted file mode 100644
index bd26a71f..00000000
--- a/Source/Core/Resources/things2d_sprite.fp
+++ /dev/null
@@ -1,43 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-// Render settings
-// w = transparency
-uniform vec4 rendersettings;
-uniform float desaturation;
-
-uniform sampler2D texture1;
-uniform vec4 texturefactor;
-
-vec3 desaturate(vec3 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return mix(texel, vec3(gray), desaturation);
-}
-
-void main()
-{
- // Take this pixel's color
- vec4 c = texture(texture1, UV);
-
- // Modulate it by selection color
- if (Color.a > 0.0)
- {
- vec3 cr = desaturate(c.rgb);
- FragColor = vec4((cr.r + Color.r) / 2.0, (cr.g + Color.g) / 2.0, (cr.b + Color.b) / 2.0, c.a * rendersettings.w * Color.a);
- }
- else
- {
- // Or leave it as it is
- FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w);
- }
-
- FragColor *= texturefactor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/things2d_thing.fp b/Source/Core/Resources/things2d_thing.fp
deleted file mode 100644
index 6e0a8106..00000000
--- a/Source/Core/Resources/things2d_thing.fp
+++ /dev/null
@@ -1,31 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-
-out vec4 FragColor;
-
-// Render settings
-// w = transparency
-uniform vec4 rendersettings;
-uniform float desaturation;
-
-uniform sampler2D texture1;
-uniform vec4 texturefactor;
-
-vec3 desaturate(vec3 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return mix(texel, vec3(gray), desaturation);
-}
-
-void main()
-{
- vec4 c = texture(texture1, UV);
- FragColor = vec4(desaturate(c.rgb), c.a * rendersettings.w) * Color;
-
- FragColor *= texturefactor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/world3d.shader b/Source/Core/Resources/world3d.shader
new file mode 100755
index 00000000..547c6b38
--- /dev/null
+++ b/Source/Core/Resources/world3d.shader
@@ -0,0 +1,359 @@
+uniforms
+{
+ mat4 world;
+ mat4 view;
+ mat4 projection;
+ mat4 modelnormal;
+ vec4 campos;
+
+ vec4 highlightcolor;
+ vec4 stencilColor;
+ float desaturation;
+
+ vec4 fogsettings;
+ vec4 fogcolor;
+ vec4 vertexColor;
+
+ sampler2D texture1;
+
+ // dynamic light related
+ vec4 lightPosAndRadius;
+ vec3 lightOrientation; // this is a vector that points in light's direction
+ vec2 light2Radius; // this is used with spotlights
+ vec4 lightColor;
+ float ignoreNormals; // ignore normals in lighting equation. used for non-attenuated lights on models.
+ float spotLight; // use lightOrientation
+}
+
+functions
+{
+ // This adds fog color to current pixel color
+ vec4 getFogColor(vec3 PosW, vec4 color)
+ {
+ float fogdist = max(16.0, distance(PosW, campos.xyz));
+ float fogfactor = exp2(campos.w * fogdist);
+
+ color.rgb = mix(lightColor.rgb, color.rgb, fogfactor);
+ return color;
+ }
+
+ vec4 desaturate(vec4 texel)
+ {
+ float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
+ return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
+ }
+}
+
+shader world3d_main
+{
+ in
+ {
+ vec3 Position;
+ vec4 Color;
+ vec2 TextureCoordinate;
+ vec3 Normal;
+ }
+
+ v2f
+ {
+ vec4 Color;
+ vec2 UV;
+ vec4 viewpos;
+ }
+
+ out
+ {
+ vec4 FragColor;
+ }
+
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.Color = in.Color;
+ v2f.UV = in.TextureCoordinate;
+ }
+
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ out.FragColor = desaturate(tcolor * v2f.Color);
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_fullbright extends world3d_main
+{
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ tcolor.a *= v2f.Color.a;
+ out.FragColor = tcolor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_main_highlight extends world3d_main
+{
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ if (tcolor.a == 0.0)
+ {
+ out.FragColor = tcolor;
+ }
+ else
+ {
+ // Blend texture color and vertex color
+ vec4 ncolor = desaturate(tcolor * v2f.Color);
+
+ out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(v2f.Color.a + 0.25, 0.5));
+ }
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_fullbright_highlight extends world3d_fullbright
+{
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ if(tcolor.a == 0.0)
+ {
+ out.FragColor = tcolor;
+ }
+ else
+ {
+ // Blend texture color and vertex color
+ vec4 ncolor = tcolor * v2f.Color;
+
+ out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (tcolor.rgb - 0.4 * highlightcolor.a), max(v2f.Color.a + 0.25, 0.5));
+ }
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_vertex_color extends world3d_main
+{
+ fragment
+ {
+ out.FragColor = v2f.Color;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_main_vertexcolor extends world3d_main
+{
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.Color = vertexColor;
+ v2f.UV = in.TextureCoordinate;
+ }
+}
+
+shader world3d_constant_color extends world3d_main_vertexcolor
+{
+ fragment
+ {
+ out.FragColor = vertexColor;
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0f) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+// world3d_main_highlight with vertex program from world3d_vertexcolor
+// to-do: rewrite into a function
+shader world3d_highlight_vertexcolor extends world3d_main_highlight
+{
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.Color = vertexColor;
+ v2f.UV = in.TextureCoordinate;
+ }
+}
+
+shader world3d_lightpass extends world3d_main
+{
+ v2f
+ {
+ vec4 Color;
+ vec2 UV;
+ vec3 PosW;
+ vec3 Normal;
+ vec4 viewpos;
+ }
+
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
+ v2f.Color = in.Color;
+ v2f.UV = in.TextureCoordinate;
+ v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
+ }
+
+ fragment
+ {
+ //is face facing away from light source?
+ // update 01.02.2017: offset the equation by 3px back to try to emulate GZDoom's broken visibility check.
+ float diffuseContribution = dot(v2f.Normal, normalize(lightPosAndRadius.xyz - v2f.PosW + v2f.Normal * 3.0));
+ if (diffuseContribution < 0.0 && ignoreNormals < 0.5)
+ discard;
+ diffuseContribution = max(diffuseContribution, 0.0); // to make sure
+
+ //is pixel in light range?
+ float dist = distance(v2f.PosW, lightPosAndRadius.xyz);
+ if (dist > lightPosAndRadius.w)
+ discard;
+
+ //is pixel tranparent?
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ if (tcolor.a == 0.0)
+ discard;
+
+ //if it is - calculate color at current pixel
+ vec4 lightColorMod = vec4(0.0, 0.0, 0.0, 1.0);
+
+ lightColorMod.rgb = lightColor.rgb * max(lightPosAndRadius.w - dist, 0.0) / lightPosAndRadius.w;
+
+ if (spotLight > 0.5)
+ {
+ vec3 lightDirection = normalize(lightPosAndRadius.xyz - v2f.PosW);
+ float cosDir = dot(lightDirection, lightOrientation);
+ float df = smoothstep(light2Radius.y, light2Radius.x, cosDir);
+ lightColorMod.rgb *= df;
+ }
+
+ if (lightColor.a > 0.979 && lightColor.a < 0.981) // attenuated light 98%
+ lightColorMod.rgb *= diffuseContribution;
+
+ if (lightColorMod.r <= 0.0 && lightColorMod.g <= 0.0 && lightColorMod.b <= 0.0)
+ discard;
+
+ lightColorMod.rgb *= lightColor.a;
+ if (lightColor.a > 0.4) //Normal, vavoom or negative light (or attenuated)
+ lightColorMod *= tcolor;
+
+ out.FragColor = desaturate(lightColorMod); //Additive light
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+ }
+}
+
+shader world3d_main_fog extends world3d_lightpass
+{
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ if (tcolor.a == 0.0)
+ {
+ out.FragColor = tcolor;
+ }
+ else
+ {
+ out.FragColor = desaturate(getFogColor(v2f.PosW, tcolor * v2f.Color));
+ }
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+shader world3d_main_highlight_fog extends world3d_main_fog
+{
+ fragment
+ {
+ vec4 tcolor = texture(texture1, v2f.UV);
+ tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
+ if (tcolor.a == 0.0)
+ {
+ out.FragColor = tcolor;
+ }
+ else
+ {
+ // Blend texture color and vertex color
+ vec4 ncolor = desaturate(getFogColor(v2f.PosW, tcolor * v2f.Color));
+
+ out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(ncolor.a + 0.25, 0.5));
+ }
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
+
+// world3d_fog, but with vertex shader from customvertexcolor_fog
+// to-do: rewrite into a function
+shader world3d_main_fog_vertexcolor extends world3d_main_fog
+{
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
+ v2f.Color = vertexColor;
+ v2f.UV = in.TextureCoordinate;
+ v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
+ }
+}
+
+shader world3d_main_highlight_fog_vertexcolor extends world3d_main_highlight_fog
+{
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
+ v2f.Color = vertexColor;
+ v2f.UV = in.TextureCoordinate;
+ v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
+ }
+}
\ No newline at end of file
diff --git a/Source/Core/Resources/world3d_constant_color.fp b/Source/Core/Resources/world3d_constant_color.fp
deleted file mode 100644
index 8e50abcf..00000000
--- a/Source/Core/Resources/world3d_constant_color.fp
+++ /dev/null
@@ -1,22 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 vertexColor;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-void main()
-{
- FragColor = vertexColor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0f) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_customvertexcolor.vp b/Source/Core/Resources/world3d_customvertexcolor.vp
deleted file mode 100644
index 05758195..00000000
--- a/Source/Core/Resources/world3d_customvertexcolor.vp
+++ /dev/null
@@ -1,23 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-in vec3 AttrNormal;
-
-out vec4 Color;
-out vec2 UV;
-out vec4 viewpos;
-
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 projection;
-
-uniform vec4 vertexColor;
-
-void main()
-{
- viewpos = view * world * vec4(AttrPosition, 1.0);
- gl_Position = projection * viewpos;
- Color = vertexColor;
- UV = AttrUV;
-}
diff --git a/Source/Core/Resources/world3d_customvertexcolor_fog.vp b/Source/Core/Resources/world3d_customvertexcolor_fog.vp
deleted file mode 100644
index 252f1867..00000000
--- a/Source/Core/Resources/world3d_customvertexcolor_fog.vp
+++ /dev/null
@@ -1,28 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-in vec3 AttrNormal;
-
-out vec4 Color;
-out vec2 UV;
-out vec3 PosW;
-out vec3 Normal;
-out vec4 viewpos;
-
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 projection;
-uniform mat4 modelnormal;
-
-uniform vec4 vertexColor;
-
-void main()
-{
- viewpos = view * world * vec4(AttrPosition, 1.0);
- gl_Position = projection * viewpos;
- PosW = (world * vec4(AttrPosition, 1.0)).xyz;
- Color = vertexColor;
- UV = AttrUV;
- Normal = normalize((modelnormal * vec4(AttrNormal, 1.0)).xyz);
-}
diff --git a/Source/Core/Resources/world3d_fullbright.fp b/Source/Core/Resources/world3d_fullbright.fp
deleted file mode 100644
index 0be00c5f..00000000
--- a/Source/Core/Resources/world3d_fullbright.fp
+++ /dev/null
@@ -1,27 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 stencilColor;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform sampler2D texture1;
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- tcolor.a *= Color.a;
- FragColor = tcolor;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_fullbright_highlight.fp b/Source/Core/Resources/world3d_fullbright_highlight.fp
deleted file mode 100644
index 1da98e35..00000000
--- a/Source/Core/Resources/world3d_fullbright_highlight.fp
+++ /dev/null
@@ -1,37 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 highlightcolor;
-uniform vec4 stencilColor;
-
-uniform sampler2D texture1;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- if(tcolor.a == 0.0)
- {
- FragColor = tcolor;
- }
- else
- {
- // Blend texture color and vertex color
- vec4 ncolor = tcolor * Color;
-
- FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (tcolor.rgb - 0.4 * highlightcolor.a), max(Color.a + 0.25, 0.5));
- }
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_lightpass.fp b/Source/Core/Resources/world3d_lightpass.fp
deleted file mode 100644
index c0fc3ba4..00000000
--- a/Source/Core/Resources/world3d_lightpass.fp
+++ /dev/null
@@ -1,74 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec3 PosW;
-in vec3 Normal;
-
-out vec4 FragColor;
-
-uniform vec4 stencilColor;
-uniform vec4 lightPosAndRadius;
-uniform vec3 lightOrientation; // this is a vector that points in light's direction
-uniform vec2 light2Radius; // this is used with spotlights
-uniform vec4 lightColor;
-uniform float ignoreNormals; // ignore normals in lighting equation. used for non-attenuated lights on models.
-uniform float spotLight; // use lightOrientation
-uniform float desaturation;
-
-uniform sampler2D texture1;
-
-vec4 desaturate(vec4 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
-}
-
-void main()
-{
- //is face facing away from light source?
- // update 01.02.2017: offset the equation by 3px back to try to emulate GZDoom's broken visibility check.
- float diffuseContribution = dot(Normal, normalize(lightPosAndRadius.xyz - PosW + Normal * 3.0));
- if (diffuseContribution < 0.0 && ignoreNormals < 0.5)
- discard;
- diffuseContribution = max(diffuseContribution, 0.0); // to make sure
-
- //is pixel in light range?
- float dist = distance(PosW, lightPosAndRadius.xyz);
- if (dist > lightPosAndRadius.w)
- discard;
-
- //is pixel tranparent?
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- if (tcolor.a == 0.0)
- discard;
-
- //if it is - calculate color at current pixel
- vec4 lightColorMod = vec4(0.0, 0.0, 0.0, 1.0);
-
- lightColorMod.rgb = lightColor.rgb * max(lightPosAndRadius.w - dist, 0.0) / lightPosAndRadius.w;
-
- if (spotLight > 0.5)
- {
- vec3 lightDirection = normalize(lightPosAndRadius.xyz - PosW);
- float cosDir = dot(lightDirection, lightOrientation);
- float df = smoothstep(light2Radius.y, light2Radius.x, cosDir);
- lightColorMod.rgb *= df;
- }
-
- if (lightColor.a > 0.979 && lightColor.a < 0.981) // attenuated light 98%
- lightColorMod.rgb *= diffuseContribution;
-
- if (lightColorMod.r <= 0.0 && lightColorMod.g <= 0.0 && lightColorMod.b <= 0.0)
- discard;
-
- lightColorMod.rgb *= lightColor.a;
- if (lightColor.a > 0.4) //Normal, vavoom or negative light (or attenuated)
- lightColorMod *= tcolor;
-
- FragColor = desaturate(lightColorMod); //Additive light
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-}
diff --git a/Source/Core/Resources/world3d_lightpass.vp b/Source/Core/Resources/world3d_lightpass.vp
deleted file mode 100644
index 94bb4633..00000000
--- a/Source/Core/Resources/world3d_lightpass.vp
+++ /dev/null
@@ -1,26 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-in vec3 AttrNormal;
-
-out vec4 Color;
-out vec2 UV;
-out vec3 PosW;
-out vec3 Normal;
-out vec4 viewpos;
-
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 projection;
-uniform mat4 modelnormal;
-
-void main()
-{
- viewpos = view * world * vec4(AttrPosition, 1.0);
- gl_Position = projection * viewpos;
- PosW = (world * vec4(AttrPosition, 1.0)).xyz;
- Color = AttrColor;
- UV = AttrUV;
- Normal = normalize((modelnormal * vec4(AttrNormal, 1.0)).xyz);
-}
diff --git a/Source/Core/Resources/world3d_main.fp b/Source/Core/Resources/world3d_main.fp
deleted file mode 100644
index 0c3bd48d..00000000
--- a/Source/Core/Resources/world3d_main.fp
+++ /dev/null
@@ -1,33 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 stencilColor;
-uniform float desaturation;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform sampler2D texture1;
-
-vec4 desaturate(vec4 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
-}
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- FragColor = desaturate(tcolor * Color);
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_main.vp b/Source/Core/Resources/world3d_main.vp
deleted file mode 100644
index 7e8ec866..00000000
--- a/Source/Core/Resources/world3d_main.vp
+++ /dev/null
@@ -1,21 +0,0 @@
-
-in vec3 AttrPosition;
-in vec4 AttrColor;
-in vec2 AttrUV;
-in vec3 AttrNormal;
-
-out vec4 Color;
-out vec2 UV;
-out vec4 viewpos;
-
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 projection;
-
-void main()
-{
- viewpos = view * world * vec4(AttrPosition, 1.0);
- gl_Position = projection * viewpos;
- Color = AttrColor;
- UV = AttrUV;
-}
diff --git a/Source/Core/Resources/world3d_main_fog.fp b/Source/Core/Resources/world3d_main_fog.fp
deleted file mode 100644
index 73d2a99e..00000000
--- a/Source/Core/Resources/world3d_main_fog.fp
+++ /dev/null
@@ -1,54 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec3 PosW;
-in vec3 Normal;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 stencilColor;
-uniform vec4 lightColor;
-uniform float desaturation;
-uniform vec4 campos; //w is set to fade factor (distance, at wich fog color completely overrides pixel color)
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform sampler2D texture1;
-
-// This adds fog color to current pixel color
-vec4 getFogColor(vec4 color)
-{
- float fogdist = max(16.0, distance(PosW, campos.xyz));
- float fogfactor = exp2(campos.w * fogdist);
-
- color.rgb = mix(lightColor.rgb, color.rgb, fogfactor);
- return color;
-}
-
-vec4 desaturate(vec4 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
-}
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- if (tcolor.a == 0.0)
- {
- FragColor = tcolor;
- }
- else
- {
- FragColor = desaturate(getFogColor(tcolor * Color));
- }
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_main_highlight.fp b/Source/Core/Resources/world3d_main_highlight.fp
deleted file mode 100644
index 5d2a76f6..00000000
--- a/Source/Core/Resources/world3d_main_highlight.fp
+++ /dev/null
@@ -1,44 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 highlightcolor;
-uniform vec4 stencilColor;
-uniform float desaturation;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform sampler2D texture1;
-
-vec4 desaturate(vec4 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
-}
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- if (tcolor.a == 0.0)
- {
- FragColor = tcolor;
- }
- else
- {
- // Blend texture color and vertex color
- vec4 ncolor = desaturate(tcolor * Color);
-
- FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(Color.a + 0.25, 0.5));
- }
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_main_highlight_fog.fp b/Source/Core/Resources/world3d_main_highlight_fog.fp
deleted file mode 100644
index 486436ae..00000000
--- a/Source/Core/Resources/world3d_main_highlight_fog.fp
+++ /dev/null
@@ -1,58 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec3 PosW;
-in vec3 Normal;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 highlightcolor;
-uniform vec4 stencilColor;
-uniform vec4 lightColor;
-uniform float desaturation;
-uniform vec4 campos; //w is set to fade factor (distance, at wich fog color completely overrides pixel color)
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform sampler2D texture1;
-
-// This adds fog color to current pixel color
-vec4 getFogColor(vec4 color)
-{
- float fogdist = max(16.0, distance(PosW, campos.xyz));
- float fogfactor = exp2(campos.w * fogdist);
-
- color.rgb = mix(lightColor.rgb, color.rgb, fogfactor);
- return color;
-}
-
-vec4 desaturate(vec4 texel)
-{
- float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
- return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
-}
-
-void main()
-{
- vec4 tcolor = texture(texture1, UV);
- tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
- if (tcolor.a == 0.0)
- {
- FragColor = tcolor;
- }
- else
- {
- // Blend texture color and vertex color
- vec4 ncolor = desaturate(getFogColor(tcolor * Color));
-
- FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(ncolor.a + 0.25, 0.5));
- }
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_skybox.fp b/Source/Core/Resources/world3d_skybox.fp
deleted file mode 100644
index 14f0bf43..00000000
--- a/Source/Core/Resources/world3d_skybox.fp
+++ /dev/null
@@ -1,24 +0,0 @@
-
-in vec3 Tex;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 highlightcolor;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-uniform samplerCube texture1;
-
-void main()
-{
- vec4 ncolor = texture(texture1, Tex);
- FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), 1.0);
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/Resources/world3d_skybox.shader b/Source/Core/Resources/world3d_skybox.shader
new file mode 100755
index 00000000..a2d11725
--- /dev/null
+++ b/Source/Core/Resources/world3d_skybox.shader
@@ -0,0 +1,59 @@
+uniforms
+{
+ mat4 world;
+ mat4 view;
+ mat4 projection;
+
+ vec4 campos; //w is set to fade factor (distance, at wich fog color completely overrides pixel color)
+
+ vec4 highlightcolor;
+
+ vec4 fogsettings;
+ vec4 fogcolor;
+
+ samplerCube texture1;
+}
+
+shader world3d_skybox
+{
+ in
+ {
+ vec3 Position;
+ vec4 Color;
+ vec2 TextureCoordinate;
+ vec3 Normal;
+ }
+
+ v2f
+ {
+ vec3 Tex;
+ vec4 viewpos;
+ }
+
+ out
+ {
+ vec4 FragColor;
+ }
+
+ vertex
+ {
+ v2f.viewpos = view * world * vec4(in.Position, 1.0);
+ gl_Position = projection * v2f.viewpos;
+ vec3 worldpos = (world * vec4(in.Position, 1.0)).xyz;
+ vec4 skynormal = vec4(0.0, 1.0, 0.0, 0.0);
+ vec3 normal = normalize((world * skynormal).xyz);
+ v2f.Tex = reflect(worldpos - campos.xyz, normal);
+ }
+
+ fragment
+ {
+ vec4 ncolor = texture(texture1, v2f.Tex);
+ out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), 1.0);
+
+ #if defined(ALPHA_TEST)
+ if (out.FragColor.a < 0.5) discard;
+ #endif
+
+ if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
+ }
+}
\ No newline at end of file
diff --git a/Source/Core/Resources/world3d_skybox.vp b/Source/Core/Resources/world3d_skybox.vp
deleted file mode 100644
index c8ecf91d..00000000
--- a/Source/Core/Resources/world3d_skybox.vp
+++ /dev/null
@@ -1,22 +0,0 @@
-
-in vec3 AttrPosition;
-in vec2 AttrUV;
-
-out vec3 Tex;
-out vec4 viewpos;
-
-uniform mat4 world;
-uniform mat4 view;
-uniform mat4 projection;
-
-uniform vec4 campos; //w is set to fade factor (distance, at wich fog color completely overrides pixel color)
-
-void main()
-{
- viewpos = view * world * vec4(AttrPosition, 1.0);
- gl_Position = projection * viewpos;
- vec3 worldpos = (world * vec4(AttrPosition, 1.0)).xyz;
- vec4 skynormal = vec4(0.0, 1.0, 0.0, 0.0);
- vec3 normal = normalize((world * skynormal).xyz);
- Tex = reflect(worldpos - campos.xyz, normal);
-}
diff --git a/Source/Core/Resources/world3d_vertex_color.fp b/Source/Core/Resources/world3d_vertex_color.fp
deleted file mode 100644
index 3100ef13..00000000
--- a/Source/Core/Resources/world3d_vertex_color.fp
+++ /dev/null
@@ -1,20 +0,0 @@
-
-in vec4 Color;
-in vec2 UV;
-in vec4 viewpos;
-
-out vec4 FragColor;
-
-uniform vec4 fogsettings;
-uniform vec4 fogcolor;
-
-void main()
-{
- FragColor = Color;
-
- #if defined(ALPHA_TEST)
- if (FragColor.a < 0.5) discard;
- #endif
-
- if (fogsettings.x >= 0.0) FragColor = mix(FragColor, fogcolor, clamp((-viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
-}
diff --git a/Source/Core/ZDoom/ZScriptTokenizer.cs b/Source/Core/ZDoom/ZScriptTokenizer.cs
index 891fe3f4..9ad89dd2 100755
--- a/Source/Core/ZDoom/ZScriptTokenizer.cs
+++ b/Source/Core/ZDoom/ZScriptTokenizer.cs
@@ -104,12 +104,24 @@ namespace CodeImp.DoomBuilder.ZDoom
WarningMessage = String.Empty;
}
+ public ZScriptToken(ZScriptToken other)
+ {
+ Type = other.Type;
+ Value = other.Value;
+ ValueInt = other.ValueInt;
+ ValueDouble = other.ValueDouble;
+ IsValid = other.IsValid;
+ WarningMessage = other.WarningMessage;
+ Position = other.Position;
+ }
+
public ZScriptTokenType Type { get; internal set; }
public string Value { get; internal set; }
public int ValueInt { get; internal set; }
public double ValueDouble { get; internal set; }
public bool IsValid { get; internal set; }
public string WarningMessage { get; internal set; }
+ public long Position { get; internal set; }
public override string ToString()
{
@@ -128,10 +140,23 @@ namespace CodeImp.DoomBuilder.ZDoom
public BinaryReader Reader { get { return reader; } }
public long LastPosition { get; private set; }
+ private List LinePositions;
+
public ZScriptTokenizer(BinaryReader br)
{
reader = br;
+ long cpos = br.BaseStream.Position;
+ LinePositions = new List();
+ br.BaseStream.Position = 0;
+ while (br.BaseStream.Position < br.BaseStream.Length)
+ {
+ byte b = br.ReadByte();
+ if (b == '\n')
+ LinePositions.Add(br.BaseStream.Position);
+ }
+ br.BaseStream.Position = cpos;
+
if (SB == null)
SB = new StringBuilder();
@@ -165,6 +190,14 @@ namespace CodeImp.DoomBuilder.ZDoom
}
}
+ public int PositionToLine(long pos)
+ {
+ for (int i = 0; i < LinePositions.Count; i++)
+ if (pos <= LinePositions[i])
+ return i+1;
+ return LinePositions.Count;
+ }
+
public void SkipWhitespace() // note that this skips both whitespace, newlines AND comments
{
while (true)
@@ -202,6 +235,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = ZScriptTokenType.Whitespace;
tok.Value = SB.ToString();
return tok;
@@ -240,6 +274,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = ZScriptTokenType.Identifier;
tok.Value = SB.ToString();
return tok;
@@ -313,6 +348,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = (isdouble ? ZScriptTokenType.Double : ZScriptTokenType.Integer);
tok.Value = SB.ToString();
try
@@ -400,6 +436,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = ZScriptTokenType.LineComment;
tok.Value = SB.ToString();
return tok;
@@ -425,6 +462,7 @@ namespace CodeImp.DoomBuilder.ZDoom
}
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = ZScriptTokenType.BlockComment;
tok.Value = SB.ToString();
return tok;
@@ -450,6 +488,7 @@ namespace CodeImp.DoomBuilder.ZDoom
else if (cnext == c)
{
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = type;
tok.Value = SB.ToString();
return tok;
@@ -478,6 +517,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// found the token.
reader.BaseStream.Position = cpos + namedtokentype.Length;
ZScriptToken tok = new ZScriptToken();
+ tok.Position = cpos;
tok.Type = namedtokentypes[namedtokentype];
tok.Value = namedtokentype;
return tok;
diff --git a/Source/Native/OpenGL/GLShader.cpp b/Source/Native/OpenGL/GLShader.cpp
index 2160dcf1..f819562c 100644
--- a/Source/Native/OpenGL/GLShader.cpp
+++ b/Source/Native/OpenGL/GLShader.cpp
@@ -77,11 +77,11 @@ void GLShader::Bind()
void GLShader::CreateProgram(GLRenderDevice* device)
{
const char* prefixNAT = R"(
- #version 150
+ #version 330
#line 1
)";
const char* prefixAT = R"(
- #version 150
+ #version 330
#define ALPHA_TEST
#line 1
)";