mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 22:41:46 +00:00
Merge branch 'master' of https://github.com/jewalky/UltimateDoomBuilder into visual-slope2
This commit is contained in:
commit
8aee7fc550
62 changed files with 2618 additions and 1862 deletions
|
@ -200,6 +200,12 @@
|
|||
<Compile Include="Data\FlatImage.cs" />
|
||||
<Compile Include="Data\ImageLoadState.cs" />
|
||||
<Compile Include="Data\Scripting\ZScriptScriptHandler.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rendering\Shaders\ShaderCompiler.cs" />
|
||||
<Compile Include="Data\UnknownImage.cs" />
|
||||
<Compile Include="Data\PatchNames.cs" />
|
||||
<Compile Include="Data\PK3Reader.cs" />
|
||||
|
@ -565,11 +571,6 @@
|
|||
<Compile Include="Plugins\Plugin.cs" />
|
||||
<Compile Include="Plugins\PluginManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rendering\Presentation.cs" />
|
||||
<Compile Include="Rendering\ColorCollection.cs" />
|
||||
<Compile Include="Rendering\ColorSetting.cs" />
|
||||
|
@ -665,17 +666,9 @@
|
|||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<EmbeddedResource Include="Resources\display2d.vp" />
|
||||
<EmbeddedResource Include="Resources\display2d_fsaa.fp" />
|
||||
<EmbeddedResource Include="Resources\display2d_fullbright.fp" />
|
||||
<EmbeddedResource Include="Resources\display2d_normal.fp" />
|
||||
<EmbeddedResource Include="Resources\display2d.shader" />
|
||||
<None Include="Resources\MissingTexture.png" />
|
||||
<EmbeddedResource Include="Resources\plotter.fp" />
|
||||
<EmbeddedResource Include="Resources\plotter.vp" />
|
||||
<EmbeddedResource Include="Resources\things2d.vp" />
|
||||
<EmbeddedResource Include="Resources\things2d_fill.fp" />
|
||||
<EmbeddedResource Include="Resources\things2d_sprite.fp" />
|
||||
<EmbeddedResource Include="Resources\things2d_thing.fp" />
|
||||
<EmbeddedResource Include="Resources\things2d.shader" />
|
||||
<None Include="Resources\UnknownImage.png" />
|
||||
<None Include="Resources\treeview.png" />
|
||||
<None Include="Resources\Folder.png" />
|
||||
|
@ -691,22 +684,8 @@
|
|||
<None Include="Resources\Status2.png" />
|
||||
<None Include="Resources\Status0.png" />
|
||||
<None Include="Resources\ColorPick.png" />
|
||||
<EmbeddedResource Include="Resources\world3d_constant_color.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_customvertexcolor.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d_customvertexcolor_fog.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d_fullbright.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_fullbright_highlight.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_lightpass.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_lightpass.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d_main.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_main.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d_main_fog.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_main_highlight.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_main_highlight_fog.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_skybox.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_skybox.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d_vertex_color.fp" />
|
||||
<EmbeddedResource Include="Resources\world3d_slopehandle.vp" />
|
||||
<EmbeddedResource Include="Resources\world3d.shader" />
|
||||
<EmbeddedResource Include="Resources\world3d_skybox.shader" />
|
||||
<None Include="Resources\Zoom.png" />
|
||||
<None Include="Resources\Properties.png" />
|
||||
<None Include="Resources\NewMap2.png" />
|
||||
|
|
|
@ -3399,16 +3399,16 @@ namespace CodeImp.DoomBuilder.Data
|
|||
General.Map.Graphics.SetSamplerState(TextureAddress.Clamp);
|
||||
|
||||
// Setup matrices
|
||||
Vector3 offset = new Vector3(0f, 0f, -1.8f); // Sphere size is 10 mu
|
||||
Vector3f offset = new Vector3f(0f, 0f, -1.8f); // Sphere size is 10 mu
|
||||
Matrix mworld = Matrix.Translation(offset) * Matrix.Scaling(1.0f, 1.0f, yscale);
|
||||
Matrix mprojection = Matrix.PerspectiveFov(Angle2D.PIHALF, 1.0f, 0.5f, 100.0f);
|
||||
|
||||
// Place camera at origin
|
||||
General.Map.Graphics.SetUniform(UniformName.campos, new Vector4());
|
||||
General.Map.Graphics.SetUniform(UniformName.campos, new Vector4f());
|
||||
|
||||
// Begin fullbright shaderpass
|
||||
General.Map.Graphics.SetShader(ShaderName.world3d_fullbright);
|
||||
General.Map.Graphics.SetUniform(UniformName.fogsettings, new Vector4(-1.0f));
|
||||
General.Map.Graphics.SetUniform(UniformName.fogsettings, new Vector4f(-1.0f));
|
||||
|
||||
// Render to the six faces of the cube map
|
||||
for (int i = 0; i < 6; i++)
|
||||
|
@ -3643,45 +3643,45 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
private static Matrix GetCubeMapViewMatrix(CubeMapFace face)
|
||||
{
|
||||
Vector3 lookdir, updir;
|
||||
Vector3f lookdir, updir;
|
||||
|
||||
switch(face)
|
||||
{
|
||||
case CubeMapFace.PositiveX:
|
||||
lookdir = new Vector3(-1.0f, 0.0f, 0.0f);
|
||||
updir = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
lookdir = new Vector3f(-1.0f, 0.0f, 0.0f);
|
||||
updir = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case CubeMapFace.NegativeX:
|
||||
lookdir = new Vector3(1.0f, 0.0f, 0.0f);
|
||||
updir = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
lookdir = new Vector3f(1.0f, 0.0f, 0.0f);
|
||||
updir = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case CubeMapFace.PositiveY:
|
||||
lookdir = new Vector3(0.0f, -1.0f, 0.0f);
|
||||
updir = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
lookdir = new Vector3f(0.0f, -1.0f, 0.0f);
|
||||
updir = new Vector3f(0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
|
||||
case CubeMapFace.NegativeY:
|
||||
lookdir = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
updir = new Vector3(0.0f, 0.0f, -1.0f);
|
||||
lookdir = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
updir = new Vector3f(0.0f, 0.0f, -1.0f);
|
||||
break;
|
||||
|
||||
case CubeMapFace.PositiveZ:
|
||||
lookdir = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
updir = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
lookdir = new Vector3f(0.0f, 0.0f, 1.0f);
|
||||
updir = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case CubeMapFace.NegativeZ:
|
||||
lookdir = new Vector3(0.0f, 0.0f, -1.0f);
|
||||
updir = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
lookdir = new Vector3f(0.0f, 0.0f, -1.0f);
|
||||
updir = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Unknown CubeMapFace!");
|
||||
}
|
||||
|
||||
Vector3 eye = new Vector3();
|
||||
Vector3f eye = new Vector3f();
|
||||
return Matrix.LookAt(eye, lookdir, updir);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
public int PrimaryRadius;
|
||||
public int SecondaryRadius;
|
||||
public int Interval;
|
||||
public Vector3 Offset;
|
||||
public Vector3f Offset;
|
||||
public bool DontLightSelf;
|
||||
|
||||
public DynamicLightData(GZGeneral.LightData type)
|
||||
{
|
||||
Type = type;
|
||||
Color = new Color3();
|
||||
Offset = new Vector3();
|
||||
Offset = new Vector3f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
#region ================== Variables
|
||||
|
||||
private ModelLoadState loadstate;
|
||||
private Vector3 scale;
|
||||
private Vector3f scale;
|
||||
private Matrix transform;
|
||||
private Matrix transformrotation;
|
||||
private Matrix transformstretched;
|
||||
|
@ -39,7 +39,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
|
||||
internal GZModel Model;
|
||||
|
||||
internal Vector3 Scale { get { return scale; } }
|
||||
internal Vector3f Scale { get { return scale; } }
|
||||
internal Matrix Transform { get { /* return (General.Settings.GZStretchView ? transformstretched : transform); */ return transformstretched; } }
|
||||
internal Matrix TransformRotation { get { return transformrotation; } }
|
||||
internal bool OverridePalette; // Used for voxel models only
|
||||
|
@ -94,7 +94,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
internal void SetTransform(Matrix rotation, Matrix offset, Vector3 scale)
|
||||
internal void SetTransform(Matrix rotation, Matrix offset, Vector3f scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
transformrotation = rotation * Matrix.Scaling(scale);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||
{
|
||||
|
@ -8,8 +9,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
|||
internal readonly List<Mesh> Meshes;
|
||||
internal readonly List<Texture> Textures;
|
||||
internal float Radius;
|
||||
internal BoundingBoxSizes BBox;
|
||||
|
||||
internal GZModel()
|
||||
internal GZModel()
|
||||
{
|
||||
Meshes = new List<Mesh>();
|
||||
Textures = new List<Texture>();
|
||||
|
|
|
@ -238,9 +238,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
|||
bbs.MinX = (int)(bbs.MinX * mde.Scale.X);
|
||||
bbs.MaxY = (int)(bbs.MaxY * mde.Scale.Y);
|
||||
bbs.MinY = (int)(bbs.MinY * mde.Scale.Y);
|
||||
bbs.MaxZ = (int)(bbs.MaxZ * mde.Scale.Z);
|
||||
bbs.MinZ = (int)(bbs.MinZ * mde.Scale.Z);
|
||||
|
||||
//calculate model radius
|
||||
mde.Model.Radius = Math.Max(Math.Max(Math.Abs(bbs.MinY), Math.Abs(bbs.MaxY)), Math.Max(Math.Abs(bbs.MinX), Math.Abs(bbs.MaxX)));
|
||||
mde.Model.BBox = bbs;
|
||||
}
|
||||
|
||||
private static Texture GetTexture(List<DataReader> containers, string texturename)
|
||||
|
@ -853,7 +856,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
|||
|
||||
List<int> polyIndecesList = new List<int>();
|
||||
List<int> uvIndecesList = new List<int>();
|
||||
List<Vector2> uvCoordsList = new List<Vector2>();
|
||||
List<Vector2f> uvCoordsList = new List<Vector2f>();
|
||||
List<WorldVertex> vertList = new List<WorldVertex>();
|
||||
|
||||
// Polygons
|
||||
|
@ -874,7 +877,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
|||
s.Position = ofs_uv + start;
|
||||
|
||||
for(int i = 0; i < num_uv; i++)
|
||||
uvCoordsList.Add(new Vector2((float)br.ReadInt16() / texWidth, (float)br.ReadInt16() / texHeight));
|
||||
uvCoordsList.Add(new Vector2f((float)br.ReadInt16() / texWidth, (float)br.ReadInt16() / texHeight));
|
||||
|
||||
// Frames
|
||||
// Find correct frame
|
||||
|
@ -910,8 +913,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
|||
s.Position = ofs_animFrame + start + frame * framesize;
|
||||
}
|
||||
|
||||
Vector3 scale = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
|
||||
Vector3 translate = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
|
||||
Vector3f scale = new Vector3f(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
|
||||
Vector3f translate = new Vector3f(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
|
||||
|
||||
s.Position += 16; // Skip frame name
|
||||
|
||||
|
|
|
@ -1937,6 +1937,9 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
if(side.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag) || side.Other == null || side.Other.Sector == null)
|
||||
return offset;
|
||||
|
||||
// Make sure the offset doesn't go in the wrong direction
|
||||
scaleY = Math.Abs(scaleY);
|
||||
|
||||
//if we don't have UpperUnpegged flag, normalize offset
|
||||
float surfaceHeight = side.GetHighHeight() * scaleY;
|
||||
return (float)Math.Round((fromNormalized ? offset + surfaceHeight : offset - surfaceHeight), General.Map.FormatInterface.VertexDecimals);
|
||||
|
@ -1947,6 +1950,9 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
{
|
||||
if(side.Sector == null) return offset;
|
||||
|
||||
// Make sure the offset doesn't go in the wrong direction
|
||||
scaleY = Math.Abs(scaleY);
|
||||
|
||||
// Normalize offset
|
||||
float surfaceHeight;
|
||||
if(side.Other != null && side.Other.Sector != null)
|
||||
|
@ -1985,7 +1991,11 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
public static float GetSidedefBottomOffsetY(Sidedef side, float offset, float scaleY, bool fromNormalized)
|
||||
{
|
||||
float surfaceHeight;
|
||||
if(side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
|
||||
// Make sure the offset doesn't go in the wrong direction
|
||||
scaleY = Math.Abs(scaleY);
|
||||
|
||||
if (side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
if(side.Other == null || side.Other.Sector == null || side.Sector.CeilTexture != General.Map.Config.SkyFlatName ||
|
||||
side.Other.Sector.CeilTexture != General.Map.Config.SkyFlatName)
|
||||
|
@ -2461,7 +2471,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
/// </summary>
|
||||
public static Vector2D HermiteSpline(Vector2D p1, Vector2D t1, Vector2D p2, Vector2D t2, float u)
|
||||
{
|
||||
return RenderDevice.V2D(Vector2.Hermite(RenderDevice.V2(p1), RenderDevice.V2(t1), RenderDevice.V2(p2), RenderDevice.V2(t2), u));
|
||||
return RenderDevice.V2D(Vector2f.Hermite(RenderDevice.V2(p1), RenderDevice.V2(t1), RenderDevice.V2(p2), RenderDevice.V2(t2), u));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2470,7 +2480,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
/// </summary>
|
||||
public static Vector3D HermiteSpline(Vector3D p1, Vector3D t1, Vector3D p2, Vector3D t2, float u)
|
||||
{
|
||||
return RenderDevice.V3D(Vector3.Hermite(RenderDevice.V3(p1), RenderDevice.V3(t1), RenderDevice.V3(p2), RenderDevice.V3(t2), u));
|
||||
return RenderDevice.V3D(Vector3f.Hermite(RenderDevice.V3(p1), RenderDevice.V3(t1), RenderDevice.V3(p2), RenderDevice.V3(t2), u));
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
|
250
Source/Core/Properties/Resources.Designer.cs
generated
250
Source/Core/Properties/Resources.Designer.cs
generated
|
@ -370,46 +370,6 @@ namespace CodeImp.DoomBuilder.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] display2d_fsaa {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("display2d_fsaa", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] display2d_fullbright {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("display2d_fullbright", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] display2d_normal {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("display2d_normal", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] display2d_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("display2d_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -1070,26 +1030,6 @@ namespace CodeImp.DoomBuilder.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] plotter {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("plotter", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] plotter_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("plotter_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -1580,46 +1520,6 @@ namespace CodeImp.DoomBuilder.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] things2d_fill {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("things2d_fill", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] things2d_sprite {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("things2d_sprite", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] things2d_thing {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("things2d_thing", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] things2d_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("things2d_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -1810,156 +1710,6 @@ namespace CodeImp.DoomBuilder.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_constant_color {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_constant_color", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_customvertexcolor_fog_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_customvertexcolor_fog_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_customvertexcolor_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_customvertexcolor_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_fullbright {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_fullbright", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_fullbright_highlight {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_fullbright_highlight", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_lightpass {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_lightpass", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_lightpass_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_lightpass_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_main {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_main", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_main_fog {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_main_fog", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_main_highlight {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_main_highlight", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_main_highlight_fog {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_main_highlight_fog", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_main_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_main_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_skybox {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_skybox", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_skybox_vp {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_skybox_vp", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] world3d_vertex_color {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("world3d_vertex_color", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -613,81 +613,6 @@
|
|||
<data name="Github" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Github.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="display2d_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\display2d.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="display2d_fsaa" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\display2d_fsaa.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="display2d_fullbright" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\display2d_fullbright.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="display2d_normal" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\display2d_normal.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="plotter_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\plotter.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="plotter" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\plotter.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="things2d_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\things2d.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="things2d_fill" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\things2d_fill.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="things2d_sprite" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\things2d_sprite.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="things2d_thing" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\things2d_thing.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_constant_color" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_constant_color.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_customvertexcolor_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_customvertexcolor.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_customvertexcolor_fog_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_customvertexcolor_fog.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_fullbright" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_fullbright.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_fullbright_highlight" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_fullbright_highlight.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_lightpass_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_lightpass.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_lightpass" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_lightpass.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_main_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_main.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_main" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_main.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_main_fog" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_main_fog.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_main_highlight" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_main_highlight.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_main_highlight_fog" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_main_highlight_fog.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_skybox_vp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_skybox.vp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_skybox" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_skybox.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="world3d_vertex_color" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\world3d_vertex_color.fp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AboutBack" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\AboutBack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
Blue = b;
|
||||
}
|
||||
|
||||
public Color3(Vector3 c)
|
||||
public Color3(Vector3f c)
|
||||
{
|
||||
Red = c.X;
|
||||
Green = c.Y;
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
Alpha = a;
|
||||
}
|
||||
|
||||
public Color4(Vector4 c)
|
||||
public Color4(Vector4f c)
|
||||
{
|
||||
Red = c.X;
|
||||
Green = c.Y;
|
||||
|
@ -60,6 +60,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return System.Drawing.Color.FromArgb(ToArgb());
|
||||
}
|
||||
|
||||
public Vector4f ToVector()
|
||||
{
|
||||
return new Vector4f(Red, Green, Blue, Alpha);
|
||||
}
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Color4)
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
public static Matrix Translation(Vector3 v)
|
||||
public static Matrix Translation(Vector3f v)
|
||||
{
|
||||
Matrix result = new Matrix();
|
||||
Matrix_Translation(v.X, v.Y, v.Z, out result);
|
||||
|
@ -229,7 +229,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Matrix Scaling(Vector3 v)
|
||||
public static Matrix Scaling(Vector3f v)
|
||||
{
|
||||
Matrix result = new Matrix();
|
||||
Matrix_Scaling(v.X, v.Y, v.Z, out result);
|
||||
|
@ -276,11 +276,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
#endif
|
||||
|
||||
public static Matrix LookAt(Vector3 eye, Vector3 target, Vector3 up)
|
||||
public static Matrix LookAt(Vector3f eye, Vector3f target, Vector3f up)
|
||||
{
|
||||
Vector3 zaxis = Vector3.Normalize(target - eye);
|
||||
Vector3 xaxis = Vector3.Normalize(Vector3.Cross(up, zaxis));
|
||||
Vector3 yaxis = Vector3.Cross(zaxis, xaxis);
|
||||
Vector3f zaxis = Vector3f.Normalize(target - eye);
|
||||
Vector3f xaxis = Vector3f.Normalize(Vector3f.Cross(up, zaxis));
|
||||
Vector3f yaxis = Vector3f.Cross(zaxis, xaxis);
|
||||
|
||||
Matrix result = Null;
|
||||
result.M11 = -xaxis.X;
|
||||
|
|
|
@ -27,6 +27,7 @@ using System.Reflection;
|
|||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using CodeImp.DoomBuilder.Rendering.Shaders;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -45,53 +46,64 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
CreateDevice();
|
||||
|
||||
DeclareUniform(UniformName.rendersettings, "rendersettings", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.rendersettings, "rendersettings", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.projection, "projection", UniformType.Mat4);
|
||||
DeclareUniform(UniformName.desaturation, "desaturation", UniformType.Float);
|
||||
DeclareUniform(UniformName.highlightcolor, "highlightcolor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.highlightcolor, "highlightcolor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.view, "view", UniformType.Mat4);
|
||||
DeclareUniform(UniformName.world, "world", UniformType.Mat4);
|
||||
DeclareUniform(UniformName.modelnormal, "modelnormal", UniformType.Mat4);
|
||||
DeclareUniform(UniformName.FillColor, "fillColor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.vertexColor, "vertexColor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.stencilColor, "stencilColor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.lightPosAndRadius, "lightPosAndRadius", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.lightOrientation, "lightOrientation", UniformType.Vec3);
|
||||
DeclareUniform(UniformName.light2Radius, "light2Radius", UniformType.Vec2);
|
||||
DeclareUniform(UniformName.lightColor, "lightColor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.FillColor, "fillColor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.vertexColor, "vertexColor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.stencilColor, "stencilColor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.lightPosAndRadius, "lightPosAndRadius", UniformType.Vec4fArray);
|
||||
DeclareUniform(UniformName.lightOrientation, "lightOrientation", UniformType.Vec4fArray);
|
||||
DeclareUniform(UniformName.light2Radius, "light2Radius", UniformType.Vec2fArray);
|
||||
DeclareUniform(UniformName.lightColor, "lightColor", UniformType.Vec4fArray);
|
||||
DeclareUniform(UniformName.ignoreNormals, "ignoreNormals", UniformType.Float);
|
||||
DeclareUniform(UniformName.spotLight, "spotLight", UniformType.Float);
|
||||
DeclareUniform(UniformName.campos, "campos", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.texturefactor, "texturefactor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.fogsettings, "fogsettings", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.fogcolor, "fogcolor", UniformType.Vec4);
|
||||
DeclareUniform(UniformName.campos, "campos", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.texturefactor, "texturefactor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.fogsettings, "fogsettings", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.fogcolor, "fogcolor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.sectorfogcolor, "sectorfogcolor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.lightsEnabled, "lightsEnabled", UniformType.Float);
|
||||
DeclareUniform(UniformName.slopeHandleLength, "slopeHandleLength", UniformType.Float);
|
||||
|
||||
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");
|
||||
|
||||
DeclareShader(ShaderName.world3d_slope_handle, "world3d_slopehandle.vp", "world3d_constant_color.fp");
|
||||
// 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");
|
||||
|
||||
SetupSettings();
|
||||
// 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");
|
||||
|
||||
// Slope handle
|
||||
CompileShader(ShaderName.world3d_slope_handle, "world3d.shader", "world3d_slope_handle");
|
||||
|
||||
SetupSettings();
|
||||
}
|
||||
|
||||
~RenderDevice()
|
||||
|
@ -112,7 +124,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
Handle = RenderDevice_New(display, RenderTarget.Handle);
|
||||
if (Handle == IntPtr.Zero)
|
||||
throw new Exception("RenderDevice_New failed");
|
||||
throw new RenderDeviceException(string.Format("Could not create render device: {0}", BuilderNative_GetError()));
|
||||
}
|
||||
|
||||
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||
|
@ -120,7 +132,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
void ThrowIfFailed(bool result)
|
||||
{
|
||||
if (!result)
|
||||
throw new RenderDeviceException(Marshal.PtrToStringAnsi(RenderDevice_GetError(Handle)));
|
||||
throw new RenderDeviceException(BuilderNative_GetError());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -142,6 +154,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<string, ShaderGroup> precompiledGroups = new Dictionary<string, ShaderGroup>();
|
||||
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);
|
||||
|
@ -152,7 +184,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
byte[] data = new byte[stream.Length];
|
||||
if (stream.Read(data, 0, data.Length) != data.Length)
|
||||
throw new Exception("Could not read resource stream");
|
||||
return Encoding.UTF8.GetString(data);
|
||||
int start = 0;
|
||||
if (data.Length >= 3 && data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf)
|
||||
start = 3;
|
||||
return Encoding.UTF8.GetString(data, start, data.Length - start);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,42 +198,104 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
public void SetUniform(UniformName uniform, bool value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value ? 1.0f : 0.0f }, 1);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value ? 1.0f : 0.0f }, 1, sizeof(float));
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, float value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value }, 1);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value }, 1, sizeof(float));
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector2 value)
|
||||
public void SetUniform(UniformName uniform, Vector2f value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y }, 2);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y }, 1, sizeof(float) * 2);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector3 value)
|
||||
public void SetUniform(UniformName uniform, Vector3f value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z }, 3);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z }, 1, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector4 value)
|
||||
public void SetUniform(UniformName uniform, Vector4f value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z, value.W }, 4);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z, value.W }, 1, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Color4 value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.Red, value.Green, value.Blue, value.Alpha }, 4);
|
||||
RenderDevice_SetUniform(Handle, uniform, new float[] { value.Red, value.Green, value.Blue, value.Alpha }, 1, sizeof(float) * 4);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Matrix matrix)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, ref matrix, 16);
|
||||
RenderDevice_SetUniform(Handle, uniform, ref matrix, 1, sizeof(float) * 16);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, ref Matrix matrix)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, ref matrix, 16);
|
||||
RenderDevice_SetUniform(Handle, uniform, ref matrix, 1, sizeof(float) * 16);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, int value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new int[] { value }, 1, sizeof(int));
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector2i value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new int[] { value.X, value.Y }, 1, sizeof(int) * 2);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector3i value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new int[] { value.X, value.Y, value.Z }, 1, sizeof(int) * 3);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector4i value)
|
||||
{
|
||||
RenderDevice_SetUniform(Handle, uniform, new int[] { value.X, value.Y, value.Z, value.W }, 1, sizeof(int) * 4);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector2f[] value)
|
||||
{
|
||||
float[] conv = new float[value.Length * 2];
|
||||
int cv = 0;
|
||||
for (int i = 0; i < conv.Length; i += 2)
|
||||
{
|
||||
conv[i] = value[cv].X;
|
||||
conv[i + 1] = value[cv].Y;
|
||||
cv++;
|
||||
}
|
||||
RenderDevice_SetUniform(Handle, uniform, conv, value.Length, sizeof(float) * conv.Length);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector3f[] value)
|
||||
{
|
||||
float[] conv = new float[value.Length * 3];
|
||||
int cv = 0;
|
||||
for (int i = 0; i < conv.Length; i += 3)
|
||||
{
|
||||
conv[i] = value[cv].X;
|
||||
conv[i + 1] = value[cv].Y;
|
||||
conv[i + 2] = value[cv].Z;
|
||||
cv++;
|
||||
}
|
||||
RenderDevice_SetUniform(Handle, uniform, conv, value.Length, sizeof(float) * conv.Length);
|
||||
}
|
||||
|
||||
public void SetUniform(UniformName uniform, Vector4f[] value)
|
||||
{
|
||||
float[] conv = new float[value.Length * 4];
|
||||
int cv = 0;
|
||||
for (int i = 0; i < conv.Length; i += 4)
|
||||
{
|
||||
conv[i] = value[cv].X;
|
||||
conv[i + 1] = value[cv].Y;
|
||||
conv[i + 2] = value[cv].Z;
|
||||
conv[i + 3] = value[cv].W;
|
||||
cv++;
|
||||
}
|
||||
RenderDevice_SetUniform(Handle, uniform, conv, value.Length, sizeof(float) * conv.Length);
|
||||
}
|
||||
|
||||
public void SetVertexBuffer(VertexBuffer buffer)
|
||||
|
@ -465,17 +562,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
static extern void RenderDevice_DeclareShader(IntPtr handle, ShaderName index, string name, string vertexShader, string fragShader);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr RenderDevice_GetError(IntPtr handle);
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
static extern string BuilderNative_GetError();
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern bool RenderDevice_SetShader(IntPtr handle, ShaderName name);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, float[] data, int count);
|
||||
static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, int[] data, int count, int bytesize);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, ref Matrix data, int count);
|
||||
static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, float[] data, int count, int bytesize);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, ref Matrix data, int count, int bytesize);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetVertexBuffer(IntPtr handle, IntPtr buffer);
|
||||
|
@ -585,25 +685,25 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
internal RenderTargetControl RenderTarget { get; private set; }
|
||||
|
||||
// This makes a Vector3 from Vector3D
|
||||
public static Vector3 V3(Vector3D v3d)
|
||||
public static Vector3f V3(Vector3D v3d)
|
||||
{
|
||||
return new Vector3(v3d.x, v3d.y, v3d.z);
|
||||
return new Vector3f(v3d.x, v3d.y, v3d.z);
|
||||
}
|
||||
|
||||
// This makes a Vector3D from Vector3
|
||||
public static Vector3D V3D(Vector3 v3)
|
||||
public static Vector3D V3D(Vector3f v3)
|
||||
{
|
||||
return new Vector3D(v3.X, v3.Y, v3.Z);
|
||||
}
|
||||
|
||||
// This makes a Vector2 from Vector2D
|
||||
public static Vector2 V2(Vector2D v2d)
|
||||
public static Vector2f V2(Vector2D v2d)
|
||||
{
|
||||
return new Vector2(v2d.x, v2d.y);
|
||||
return new Vector2f(v2d.x, v2d.y);
|
||||
}
|
||||
|
||||
// This makes a Vector2D from Vector2
|
||||
public static Vector2D V2D(Vector2 v2)
|
||||
public static Vector2D V2D(Vector2f v2)
|
||||
{
|
||||
return new Vector2D(v2.X, v2.Y);
|
||||
}
|
||||
|
@ -617,7 +717,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
things2d_thing,
|
||||
things2d_sprite,
|
||||
things2d_fill,
|
||||
plotter,
|
||||
world3d_main,
|
||||
world3d_fullbright,
|
||||
world3d_main_highlight,
|
||||
|
@ -635,17 +734,23 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
world3d_main_highlight_fog_vertexcolor,
|
||||
world3d_vertex_color,
|
||||
world3d_constant_color,
|
||||
world3d_lightpass,
|
||||
world3d_slope_handle
|
||||
}
|
||||
|
||||
public enum UniformType : int
|
||||
{
|
||||
Vec4,
|
||||
Vec3,
|
||||
Vec2,
|
||||
Vec4f,
|
||||
Vec3f,
|
||||
Vec2f,
|
||||
Float,
|
||||
Mat4
|
||||
Mat4,
|
||||
Vec4i,
|
||||
Vec3i,
|
||||
Vec2i,
|
||||
Int,
|
||||
Vec4fArray,
|
||||
Vec3fArray,
|
||||
Vec2fArray
|
||||
}
|
||||
|
||||
public enum UniformName : int
|
||||
|
@ -670,6 +775,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
texturefactor,
|
||||
fogsettings,
|
||||
fogcolor,
|
||||
sectorfogcolor,
|
||||
lightsEnabled,
|
||||
slopeHandleLength
|
||||
}
|
||||
|
||||
|
|
|
@ -487,7 +487,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
private void SetDisplay2DSettings(float texelx, float texely, float fsaafactor, float alpha, bool bilinear, bool flipY = false)
|
||||
{
|
||||
Vector4 values = new Vector4(texelx, texely, fsaafactor, alpha);
|
||||
Vector4f values = new Vector4f(texelx, texely, fsaafactor, alpha);
|
||||
graphics.SetUniform(UniformName.rendersettings, values);
|
||||
if (flipY)
|
||||
graphics.SetUniform(UniformName.projection, worldmatrix * viewmatrix * Matrix.Scaling(1f, -1f, 1f));
|
||||
|
@ -498,7 +498,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
private void SetThings2DSettings(float alpha)
|
||||
{
|
||||
Vector4 values = new Vector4(0.0f, 0.0f, 1.0f, alpha);
|
||||
Vector4f values = new Vector4f(0.0f, 0.0f, 1.0f, alpha);
|
||||
graphics.SetUniform(UniformName.rendersettings, values);
|
||||
graphics.SetUniform(UniformName.projection, worldmatrix * viewmatrix);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
private const float PROJ_NEAR_PLANE = 1f;
|
||||
private const float FOG_RANGE = 0.9f;
|
||||
private const int MAX_DYNLIGHTS_PER_SURFACE = 64;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -287,7 +288,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
General.Settings.ViewDistance, Angle2D.DegToRad(General.Settings.VisualFOV));
|
||||
|
||||
// Make the view matrix
|
||||
view3d = Matrix.LookAt(RenderDevice.V3(pos), RenderDevice.V3(lookat), new Vector3(0f, 0f, 1f));
|
||||
view3d = Matrix.LookAt(RenderDevice.V3(pos), RenderDevice.V3(lookat), new Vector3f(0f, 0f, 1f));
|
||||
|
||||
// Make the billboard matrix
|
||||
billboard = Matrix.RotationZ(anglexy + Angle2D.PI);
|
||||
|
@ -322,7 +323,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetAlphaTestEnable(false);
|
||||
graphics.SetSourceBlend(Blend.SourceAlpha);
|
||||
graphics.SetDestinationBlend(Blend.InverseSourceAlpha);
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4(-1.0f));
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4f(-1.0f));
|
||||
graphics.SetUniform(UniformName.fogcolor, General.Colors.Background.ToColorValue());
|
||||
graphics.SetUniform(UniformName.texturefactor, new Color4(1f, 1f, 1f, 1f));
|
||||
graphics.SetUniform(UniformName.highlightcolor, new Color4()); //mxd
|
||||
|
@ -412,14 +413,14 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// SOLID PASS
|
||||
world = Matrix.Identity;
|
||||
graphics.SetUniform(UniformName.world, ref world);
|
||||
RenderSinglePass(solidgeo, solidthings);
|
||||
RenderSinglePass(solidgeo, solidthings, lightthings);
|
||||
|
||||
//mxd. Render models, without backface culling
|
||||
if(maskedmodelthings.Count > 0)
|
||||
{
|
||||
graphics.SetAlphaTestEnable(true);
|
||||
graphics.SetCullMode(Cull.None);
|
||||
RenderModels(false, false);
|
||||
RenderModels(false, lightthings);
|
||||
graphics.SetCullMode(Cull.Clockwise);
|
||||
}
|
||||
|
||||
|
@ -429,33 +430,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
world = Matrix.Identity;
|
||||
graphics.SetUniform(UniformName.world, ref world);
|
||||
graphics.SetAlphaTestEnable(true);
|
||||
RenderSinglePass(maskedgeo, maskedthings);
|
||||
RenderSinglePass(maskedgeo, maskedthings, lightthings);
|
||||
}
|
||||
|
||||
//mxd. LIGHT PASS
|
||||
if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && lightthings.Count > 0)
|
||||
{
|
||||
world = Matrix.Identity;
|
||||
graphics.SetUniform(UniformName.world, ref world);
|
||||
graphics.SetAlphaBlendEnable(true);
|
||||
graphics.SetAlphaTestEnable(false);
|
||||
graphics.SetZWriteEnable(false);
|
||||
graphics.SetDestinationBlend(Blend.One);
|
||||
|
||||
RenderLights(solidgeo, lightthings);
|
||||
RenderLights(maskedgeo, lightthings);
|
||||
|
||||
if (maskedmodelthings.Count > 0)
|
||||
{
|
||||
graphics.SetAlphaTestEnable(true);
|
||||
graphics.SetCullMode(Cull.None);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, true);
|
||||
RenderModels(true, false);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, false);
|
||||
graphics.SetCullMode(Cull.Clockwise);
|
||||
}
|
||||
}
|
||||
|
||||
// ALPHA AND ADDITIVE PASS
|
||||
if(translucentgeo.Count > 0 || translucentthings.Count > 0)
|
||||
{
|
||||
|
@ -465,21 +442,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetAlphaTestEnable(false);
|
||||
graphics.SetZWriteEnable(false);
|
||||
graphics.SetSourceBlend(Blend.SourceAlpha);
|
||||
RenderTranslucentPass(translucentgeo, translucentthings);
|
||||
RenderTranslucentPass(translucentgeo, translucentthings, lightthings);
|
||||
}
|
||||
|
||||
// [ZZ] LIGHT PASS on ALPHA GEOMETRY (GZDoom does this)
|
||||
if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && lightthings.Count > 0 && translucentgeo.Count > 0)
|
||||
{
|
||||
world = Matrix.Identity;
|
||||
graphics.SetUniform(UniformName.world, ref world);
|
||||
graphics.SetAlphaBlendEnable(true);
|
||||
graphics.SetAlphaTestEnable(false);
|
||||
graphics.SetZWriteEnable(false);
|
||||
graphics.SetDestinationBlend(Blend.One);
|
||||
RenderTranslucentLights(translucentgeo, lightthings);
|
||||
}
|
||||
|
||||
//mxd. Render translucent models, with backface culling
|
||||
if(translucentmodelthings.Count > 0)
|
||||
{
|
||||
|
@ -487,16 +452,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetAlphaTestEnable(false);
|
||||
graphics.SetZWriteEnable(false);
|
||||
graphics.SetSourceBlend(Blend.SourceAlpha);
|
||||
RenderModels(false, true);
|
||||
}
|
||||
|
||||
// [ZZ] light pass on alpha models
|
||||
if (General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && lightthings.Count > 0 && translucentmodelthings.Count > 0)
|
||||
{
|
||||
graphics.SetAlphaTestEnable(true);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, true);
|
||||
RenderModels(true, true);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, false);
|
||||
RenderModels(true, lightthings);
|
||||
}
|
||||
|
||||
// THING CAGES
|
||||
|
@ -801,17 +757,28 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
// This performs a single render pass
|
||||
private void RenderSinglePass(Dictionary<ImageData, List<VisualGeometry>> geopass, Dictionary<ImageData, List<VisualThing>> thingspass)
|
||||
private void RenderSinglePass(Dictionary<ImageData, List<VisualGeometry>> geopass, Dictionary<ImageData, List<VisualThing>> thingspass, List<VisualThing> lights)
|
||||
{
|
||||
ImageData curtexture;
|
||||
ShaderName currentshaderpass = shaderpass;
|
||||
ShaderName highshaderpass = (ShaderName)(shaderpass + 2);
|
||||
|
||||
// Begin rendering with this shader
|
||||
graphics.SetShader(shaderpass);
|
||||
// Begin rendering with this shader
|
||||
graphics.SetShader(shaderpass);
|
||||
|
||||
// Render the geometry collected
|
||||
foreach(KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
|
||||
// Light data arrays
|
||||
Vector4f[] lightColor = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightPosAndRadius = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightOrientation = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector2f[] light2Radius = new Vector2f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
|
||||
graphics.SetUniform(UniformName.lightsEnabled, lights.Count > 0);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, false);
|
||||
|
||||
bool hadlights = false;
|
||||
|
||||
// Render the geometry collected
|
||||
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
|
||||
{
|
||||
// What texture to use?
|
||||
if(group.Key is UnknownImage)
|
||||
|
@ -832,6 +799,54 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
foreach(VisualGeometry g in group.Value)
|
||||
{
|
||||
|
||||
int lightIndex = 0;
|
||||
|
||||
foreach (VisualThing light in lights)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, light.BoundingBox))
|
||||
{
|
||||
|
||||
//t.LightType.LightRenderStyle
|
||||
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
|
||||
|
||||
lightColor[lightIndex] = light.LightColor.ToVector();
|
||||
lightPosAndRadius[lightIndex] = new Vector4f(light.Center, light.LightRadius);
|
||||
|
||||
// set type of light
|
||||
if (light.LightType.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
lightOrientation[lightIndex] = new Vector4f(light.VectorLookAt, 1f);
|
||||
light2Radius[lightIndex] = new Vector2f(CosDeg(light.LightSpotRadius1), CosDeg(light.LightSpotRadius2));
|
||||
}
|
||||
else lightOrientation[lightIndex].W = 0f;
|
||||
|
||||
lightIndex++;
|
||||
|
||||
if (lightIndex >= lightColor.Length)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool havelights = (lightIndex > 0);
|
||||
|
||||
for (int i = lightIndex; i < lightColor.Length; i++)
|
||||
lightColor[i].W = 0;
|
||||
|
||||
if (havelights != hadlights || havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightColor, lightColor);
|
||||
if (havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lightPosAndRadius);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lightOrientation);
|
||||
graphics.SetUniform(UniformName.light2Radius, light2Radius);
|
||||
}
|
||||
}
|
||||
|
||||
hadlights = havelights;
|
||||
|
||||
// Changing sector?
|
||||
if(!object.ReferenceEquals(g.Sector, sector))
|
||||
{
|
||||
|
@ -880,8 +895,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd. Set variables for fog rendering?
|
||||
if(wantedshaderpass > ShaderName.world3d_p7)
|
||||
{
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, g.FogFactor));
|
||||
graphics.SetUniform(UniformName.lightColor, sector.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, g.FogFactor));
|
||||
graphics.SetUniform(UniformName.sectorfogcolor, sector.Sector.FogColor);
|
||||
}
|
||||
|
||||
// Set the colors to use
|
||||
|
@ -896,8 +911,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
// Get things for this pass
|
||||
if(thingspass.Count > 0)
|
||||
graphics.SetUniform(UniformName.lightsEnabled, false);
|
||||
|
||||
// Get things for this pass
|
||||
if (thingspass.Count > 0)
|
||||
{
|
||||
// Texture addressing
|
||||
graphics.SetSamplerState(TextureAddress.Clamp);
|
||||
|
@ -974,11 +991,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
if(wantedshaderpass > ShaderName.world3d_p7)
|
||||
{
|
||||
graphics.SetUniform(UniformName.modelnormal, Matrix.Identity);
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
}
|
||||
|
||||
// Set the colors to use
|
||||
if(t.Thing.Sector != null) graphics.SetUniform(UniformName.lightColor, t.Thing.Sector.FogColor);
|
||||
if(t.Thing.Sector != null) graphics.SetUniform(UniformName.sectorfogcolor, t.Thing.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.vertexColor, vertexcolor);
|
||||
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)));
|
||||
|
||||
|
@ -1012,7 +1029,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
//mxd
|
||||
private void RenderTranslucentPass(List<VisualGeometry> geopass, List<VisualThing> thingspass)
|
||||
private void RenderTranslucentPass(List<VisualGeometry> geopass, List<VisualThing> thingspass, List<VisualThing> lights)
|
||||
{
|
||||
ShaderName currentshaderpass = shaderpass;
|
||||
ShaderName highshaderpass = (ShaderName)(shaderpass + 2);
|
||||
|
@ -1020,12 +1037,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Sort geometry by camera distance. First vertex of the BoundingBox is it's center
|
||||
geopass.Sort(delegate(VisualGeometry vg1, VisualGeometry vg2)
|
||||
{
|
||||
/*if(vg1 == vg2) return 0;
|
||||
return (int)((General.Map.VisualCamera.Position - vg2.BoundingBox[0]).GetLengthSq()
|
||||
-(General.Map.VisualCamera.Position - vg1.BoundingBox[0]).GetLengthSq());*/
|
||||
|
||||
// This does not work when you have huge translucent 3D floor combined with small translucent something over it.
|
||||
// The huge translucent 3D floor may easily have it's center CLOSER and thus get drawn over everything, which is certainly not expected behavior.
|
||||
|
||||
if (vg1 == vg2)
|
||||
return 0;
|
||||
|
@ -1049,6 +1060,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
return (int)(dist2 - dist1);
|
||||
|
||||
});
|
||||
|
||||
ImageData curtexture;
|
||||
|
@ -1060,11 +1072,71 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Begin rendering with this shader
|
||||
graphics.SetShader(shaderpass);
|
||||
|
||||
// Go for all geometry
|
||||
foreach(VisualGeometry g in geopass)
|
||||
|
||||
// Light data arrays
|
||||
Vector4f[] lightColor = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightPosAndRadius = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightOrientation = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector2f[] light2Radius = new Vector2f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
|
||||
graphics.SetUniform(UniformName.lightsEnabled, lights.Count > 0);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, false);
|
||||
|
||||
bool hadlights = false;
|
||||
|
||||
// Go for all geometry
|
||||
foreach (VisualGeometry g in geopass)
|
||||
{
|
||||
// Change blend mode?
|
||||
if(g.RenderPass != currentpass)
|
||||
|
||||
int lightIndex = 0;
|
||||
|
||||
foreach (VisualThing light in lights)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, light.BoundingBox))
|
||||
{
|
||||
|
||||
//t.LightType.LightRenderStyle
|
||||
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
|
||||
|
||||
lightColor[lightIndex] = light.LightColor.ToVector();
|
||||
lightPosAndRadius[lightIndex] = new Vector4f(light.Center, light.LightRadius);
|
||||
|
||||
// set type of light
|
||||
if (light.LightType.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
lightOrientation[lightIndex] = new Vector4f(light.VectorLookAt, 1f);
|
||||
light2Radius[lightIndex] = new Vector2f(CosDeg(light.LightSpotRadius1), CosDeg(light.LightSpotRadius2));
|
||||
}
|
||||
else lightOrientation[lightIndex].W = 0f;
|
||||
|
||||
lightIndex++;
|
||||
|
||||
if (lightIndex >= lightColor.Length)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool havelights = (lightIndex > 0);
|
||||
|
||||
for (int i = lightIndex; i < lightColor.Length; i++)
|
||||
lightColor[i].W = 0;
|
||||
|
||||
if (havelights != hadlights || havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightColor, lightColor);
|
||||
if (havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lightPosAndRadius);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lightOrientation);
|
||||
graphics.SetUniform(UniformName.light2Radius, light2Radius);
|
||||
}
|
||||
}
|
||||
|
||||
hadlights = havelights;
|
||||
|
||||
// Change blend mode?
|
||||
if (g.RenderPass != currentpass)
|
||||
{
|
||||
switch(g.RenderPass)
|
||||
{
|
||||
|
@ -1143,7 +1215,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Set variables for fog rendering?
|
||||
if (wantedshaderpass > ShaderName.world3d_p7 && g.FogFactor != fogfactor)
|
||||
{
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, g.FogFactor));
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, g.FogFactor));
|
||||
fogfactor = g.FogFactor;
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1223,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetUniform(UniformName.desaturation, sector.Sector.Desaturation);
|
||||
|
||||
// Set the colors to use
|
||||
graphics.SetUniform(UniformName.lightColor, sector.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.sectorfogcolor, sector.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((g == highlighted) && showhighlight, (g.Selected && showselection)));
|
||||
|
||||
// Render!
|
||||
|
@ -1160,8 +1232,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
else graphics.SetUniform(UniformName.desaturation, 0.0f);
|
||||
}
|
||||
|
||||
// Get things for this pass
|
||||
if(thingspass.Count > 0)
|
||||
graphics.SetUniform(UniformName.lightsEnabled, false);
|
||||
|
||||
// Get things for this pass
|
||||
if (thingspass.Count > 0)
|
||||
{
|
||||
// Texture addressing
|
||||
graphics.SetSamplerState(TextureAddress.Clamp);
|
||||
|
@ -1272,13 +1346,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetUniform(UniformName.modelnormal, Matrix.Identity);
|
||||
if (t.FogFactor != fogfactor)
|
||||
{
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
fogfactor = t.FogFactor;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the colors to use
|
||||
graphics.SetUniform(UniformName.lightColor, t.Thing.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.sectorfogcolor, t.Thing.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.vertexColor, vertexcolor);
|
||||
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)));
|
||||
|
||||
|
@ -1349,206 +1423,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return (float)Math.Cos(Angle2D.DegToRad(angle));
|
||||
}
|
||||
|
||||
//mxd. Dynamic lights pass!
|
||||
private VisualSector RenderLightsFromGeometryList(List<VisualGeometry> geometrytolit, List<VisualThing> lights, VisualSector sector, bool settexture)
|
||||
{
|
||||
foreach (VisualGeometry g in geometrytolit)
|
||||
{
|
||||
// Changing sector?
|
||||
if (!object.ReferenceEquals(g.Sector, sector))
|
||||
{
|
||||
// Only do this sector when a vertexbuffer is created
|
||||
// mxd. no Map means that sector was deleted recently, I suppose
|
||||
if (g.Sector.GeometryBuffer != null && g.Sector.Sector.Map != null)
|
||||
{
|
||||
// Change current sector
|
||||
sector = g.Sector;
|
||||
|
||||
// Set stream source
|
||||
graphics.SetVertexBuffer(sector.GeometryBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sector = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (sector == null) continue;
|
||||
|
||||
graphics.SetUniform(UniformName.desaturation, sector.Sector.Desaturation);
|
||||
|
||||
// note: additive geometry doesn't receive lighting
|
||||
if (g.RenderPass == RenderPass.Additive)
|
||||
continue;
|
||||
|
||||
if (settexture)
|
||||
graphics.SetTexture(g.Texture.Texture);
|
||||
|
||||
//normal lights
|
||||
int count = lightOffsets[0];
|
||||
Vector4 lpr;
|
||||
if (lightOffsets[0] > 0)
|
||||
{
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
graphics.Draw(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//attenuated lights
|
||||
if (lightOffsets[1] > 0)
|
||||
{
|
||||
count += lightOffsets[1];
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = lightOffsets[0]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
graphics.Draw(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//additive lights
|
||||
if (lightOffsets[2] > 0)
|
||||
{
|
||||
count += lightOffsets[2];
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = lightOffsets[0] + lightOffsets[1]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
graphics.Draw(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//negative lights
|
||||
if (lightOffsets[3] > 0)
|
||||
{
|
||||
count += lightOffsets[3];
|
||||
graphics.SetBlendOperation(BlendOperation.ReverseSubtract);
|
||||
|
||||
for (int i = lightOffsets[0] + lightOffsets[1] + lightOffsets[2]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(g.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
Color4 lc = lights[i].LightColor;
|
||||
graphics.SetUniform(UniformName.lightColor, new Color4((lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2, lc.Alpha));
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
graphics.Draw(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sector;
|
||||
}
|
||||
|
||||
// [ZZ] split into RenderLights and RenderTranslucentLights
|
||||
private void RenderTranslucentLights(List<VisualGeometry> geometrytolit, List<VisualThing> lights)
|
||||
{
|
||||
if (geometrytolit.Count == 0) return;
|
||||
|
||||
graphics.SetUniform(UniformName.modelnormal, Matrix.Identity);
|
||||
graphics.SetShader(ShaderName.world3d_lightpass);
|
||||
graphics.SetAlphaBlendEnable(true);
|
||||
|
||||
VisualSector sector = null;
|
||||
|
||||
graphics.SetSourceBlend(Blend.One);
|
||||
graphics.SetDestinationBlend(Blend.One);
|
||||
|
||||
//
|
||||
RenderLightsFromGeometryList(geometrytolit, lights, sector, true);
|
||||
|
||||
//
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
graphics.SetAlphaBlendEnable(false);
|
||||
}
|
||||
|
||||
//
|
||||
private void RenderLights(Dictionary<ImageData, List<VisualGeometry>> geometrytolit, List<VisualThing> lights)
|
||||
{
|
||||
// Anything to do?
|
||||
if (geometrytolit.Count == 0) return;
|
||||
|
||||
graphics.SetUniform(UniformName.modelnormal, Matrix.Identity);
|
||||
graphics.SetShader(ShaderName.world3d_lightpass);
|
||||
graphics.SetAlphaBlendEnable(true);
|
||||
|
||||
VisualSector sector = null;
|
||||
|
||||
graphics.SetSourceBlend(Blend.One);
|
||||
graphics.SetDestinationBlend(Blend.One);
|
||||
|
||||
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geometrytolit)
|
||||
{
|
||||
if (group.Key.Texture == null) continue;
|
||||
graphics.SetTexture(group.Key.Texture);
|
||||
|
||||
sector = RenderLightsFromGeometryList(group.Value, lights, sector, false);
|
||||
}
|
||||
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
graphics.SetAlphaBlendEnable(false);
|
||||
}
|
||||
|
||||
//mxd. Render models
|
||||
private void RenderModels(bool lightpass, bool trans)
|
||||
private void RenderModels(bool trans, List<VisualThing> lights)
|
||||
{
|
||||
ShaderName shaderpass = (fullbrightness ? ShaderName.world3d_fullbright : ShaderName.world3d_main_vertexcolor);
|
||||
ShaderName currentshaderpass = shaderpass;
|
||||
|
@ -1557,15 +1433,18 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
RenderPass currentpass = RenderPass.Solid;
|
||||
|
||||
// Begin rendering with this shader
|
||||
if (!lightpass)
|
||||
{
|
||||
graphics.SetShader(currentshaderpass);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.SetShader(ShaderName.world3d_lightpass);
|
||||
graphics.SetAlphaBlendEnable(true);
|
||||
}
|
||||
graphics.SetShader(currentshaderpass);
|
||||
|
||||
// Light data arrays
|
||||
Vector4f[] lightColor = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightPosAndRadius = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector4f[] lightOrientation = new Vector4f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
Vector2f[] light2Radius = new Vector2f[MAX_DYNLIGHTS_PER_SURFACE];
|
||||
|
||||
graphics.SetUniform(UniformName.lightsEnabled, lights.Count > 0);
|
||||
graphics.SetUniform(UniformName.ignoreNormals, true);
|
||||
|
||||
bool hadlights = false;
|
||||
|
||||
List<VisualThing> things;
|
||||
if (trans)
|
||||
|
@ -1585,6 +1464,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
foreach(VisualThing t in things)
|
||||
{
|
||||
|
||||
if (trans)
|
||||
{
|
||||
// Change blend mode?
|
||||
|
@ -1625,7 +1505,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
wantedshaderpass += 8;
|
||||
|
||||
// Switch shader pass?
|
||||
if (!lightpass && currentshaderpass != wantedshaderpass)
|
||||
if (currentshaderpass != wantedshaderpass)
|
||||
{
|
||||
graphics.SetShader(wantedshaderpass);
|
||||
currentshaderpass = wantedshaderpass;
|
||||
|
@ -1649,147 +1529,73 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
// this is not right...
|
||||
graphics.SetUniform(UniformName.modelnormal, General.Map.Data.ModeldefEntries[t.Thing.Type].TransformRotation * modelrotation);
|
||||
if (t.Thing.Sector != null) graphics.SetUniform(UniformName.lightColor, t.Thing.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
if (t.Thing.Sector != null) graphics.SetUniform(UniformName.sectorfogcolor, t.Thing.Sector.FogColor);
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, t.FogFactor));
|
||||
}
|
||||
|
||||
if (t.Thing.Sector != null)
|
||||
graphics.SetUniform(UniformName.desaturation, t.Thing.Sector.Desaturation);
|
||||
else graphics.SetUniform(UniformName.desaturation, 0.0f);
|
||||
|
||||
int lightIndex = 0;
|
||||
|
||||
foreach (VisualThing light in lights)
|
||||
{
|
||||
if (BoundingBoxesIntersect(t.BoundingBox, light.BoundingBox))
|
||||
{
|
||||
|
||||
//t.LightType.LightRenderStyle
|
||||
//Vector4f lightColor, lightPosAndRadius, lightOrientation, light2Radius;
|
||||
|
||||
lightColor[lightIndex] = light.LightColor.ToVector();
|
||||
lightPosAndRadius[lightIndex] = new Vector4f(light.Center, light.LightRadius);
|
||||
|
||||
// set type of light
|
||||
if (light.LightType.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
lightOrientation[lightIndex] = new Vector4f(light.VectorLookAt, 1f);
|
||||
light2Radius[lightIndex] = new Vector2f(CosDeg(light.LightSpotRadius1), CosDeg(light.LightSpotRadius2));
|
||||
}
|
||||
else lightOrientation[lightIndex].W = 0f;
|
||||
|
||||
lightIndex++;
|
||||
|
||||
if (lightIndex >= lightColor.Length)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool havelights = (lightIndex > 0);
|
||||
|
||||
for (int i = lightIndex; i < lightColor.Length; i++)
|
||||
lightColor[i].W = 0;
|
||||
|
||||
if (hadlights != havelights || havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightColor, lightColor);
|
||||
if (havelights)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lightPosAndRadius);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lightOrientation);
|
||||
graphics.SetUniform(UniformName.light2Radius, light2Radius);
|
||||
}
|
||||
}
|
||||
|
||||
hadlights = havelights;
|
||||
|
||||
GZModel model = General.Map.Data.ModeldefEntries[t.Thing.Type].Model;
|
||||
for (int j = 0; j < model.Meshes.Count; j++)
|
||||
{
|
||||
graphics.SetTexture(model.Textures[j]);
|
||||
|
||||
if (!lightpass)
|
||||
{
|
||||
// Render!
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
else if (lightpass && t.RenderPass != RenderPass.Additive) // additive stuff does not get any lighting
|
||||
{
|
||||
List<VisualThing> lights = lightthings;
|
||||
//
|
||||
int count = lightOffsets[0];
|
||||
Vector4 lpr;
|
||||
|
||||
// normal lights
|
||||
if (lightOffsets[0] > 0)
|
||||
{
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(t.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//attenuated lights
|
||||
if (lightOffsets[1] > 0)
|
||||
{
|
||||
count += lightOffsets[1];
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = lightOffsets[0]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(t.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//additive lights
|
||||
if (lightOffsets[2] > 0)
|
||||
{
|
||||
count += lightOffsets[2];
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
|
||||
for (int i = lightOffsets[0] + lightOffsets[1]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(t.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
graphics.SetUniform(UniformName.lightColor, lights[i].LightColor);
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//negative lights
|
||||
if (lightOffsets[3] > 0)
|
||||
{
|
||||
count += lightOffsets[3];
|
||||
graphics.SetBlendOperation(BlendOperation.ReverseSubtract);
|
||||
|
||||
for (int i = lightOffsets[0] + lightOffsets[1] + lightOffsets[2]; i < count; i++)
|
||||
{
|
||||
if (BoundingBoxesIntersect(t.BoundingBox, lights[i].BoundingBox))
|
||||
{
|
||||
lpr = new Vector4(lights[i].Center, lights[i].LightRadius);
|
||||
if (lpr.W == 0) continue;
|
||||
Color4 lc = lights[i].LightColor;
|
||||
graphics.SetUniform(UniformName.lightColor, new Color4((lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2, lc.Alpha));
|
||||
graphics.SetUniform(UniformName.lightPosAndRadius, lpr);
|
||||
GZGeneral.LightData ld = lights[i].LightType;
|
||||
if (ld.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
graphics.SetUniform(UniformName.spotLight, true);
|
||||
graphics.SetUniform(UniformName.lightOrientation, lights[i].VectorLookAt);
|
||||
graphics.SetUniform(UniformName.light2Radius, new Vector2(CosDeg(lights[i].LightSpotRadius1), CosDeg(lights[i].LightSpotRadius2)));
|
||||
}
|
||||
else graphics.SetUniform(UniformName.spotLight, false);
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Render!
|
||||
model.Meshes[j].Draw(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
if (lightpass)
|
||||
{
|
||||
graphics.SetBlendOperation(BlendOperation.Add);
|
||||
graphics.SetAlphaBlendEnable(false);
|
||||
}
|
||||
graphics.SetUniform(UniformName.lightsEnabled, false);
|
||||
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -1800,7 +1606,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Set render settings
|
||||
graphics.SetShader(ShaderName.world3d_skybox);
|
||||
graphics.SetTexture(General.Map.Data.SkyBox);
|
||||
graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, 0f));
|
||||
graphics.SetUniform(UniformName.campos, new Vector4f(cameraposition.x, cameraposition.y, cameraposition.z, 0f));
|
||||
|
||||
foreach(VisualGeometry g in geo)
|
||||
{
|
||||
|
@ -1853,20 +1659,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
if(General.Map.Data.GldefsEntries.ContainsKey(t.Thing.Type) && General.Map.Data.GldefsEntries[t.Thing.Type].DontLightSelf && t.Thing.Index == lt.Thing.Index)
|
||||
continue;
|
||||
|
||||
float distSquared = Vector3.DistanceSquared(lt.Center, t.Center);
|
||||
float distSquared = Vector3f.DistanceSquared(lt.Center, t.Center);
|
||||
float radiusSquared = lt.LightRadius * lt.LightRadius;
|
||||
if(distSquared < radiusSquared)
|
||||
{
|
||||
int sign = (lt.LightType.LightRenderStyle == GZGeneral.LightRenderStyle.SUBTRACTIVE ? -1 : 1);
|
||||
Vector3 L = (t.Center - lt.Center);
|
||||
Vector3f L = (t.Center - lt.Center);
|
||||
float dist = L.Length();
|
||||
float scaler = 1 - dist / lt.LightRadius * lt.LightColor.Alpha;
|
||||
|
||||
if (lt.LightType.LightType == GZGeneral.LightType.SPOT)
|
||||
{
|
||||
Vector3 lookAt = lt.VectorLookAt;
|
||||
Vector3f lookAt = lt.VectorLookAt;
|
||||
L.Normalize();
|
||||
float cosDir = Vector3.Dot(-L, lookAt);
|
||||
float cosDir = Vector3f.Dot(-L, lookAt);
|
||||
scaler *= (float)Smoothstep(CosDeg(lt.LightSpotRadius2), CosDeg(lt.LightSpotRadius1), cosDir);
|
||||
}
|
||||
|
||||
|
@ -2061,7 +1867,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetShader(ShaderName.display2d_normal);
|
||||
graphics.SetUniform(UniformName.projection, world * view2d);
|
||||
graphics.SetUniform(UniformName.texturefactor, new Color4(1f, 1f, 1f, 1f));
|
||||
graphics.SetUniform(UniformName.rendersettings, new Vector4(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
graphics.SetUniform(UniformName.rendersettings, new Vector4f(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
graphics.SetSamplerFilter(General.Settings.VisualBilinear ? TextureFilter.Linear : TextureFilter.Nearest);
|
||||
|
||||
// Texture
|
||||
|
@ -2085,11 +1891,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
if (usefog)
|
||||
{
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4(General.Settings.ViewDistance * FOG_RANGE, General.Settings.ViewDistance, 0.0f, 0.0f));
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4f(General.Settings.ViewDistance * FOG_RANGE, General.Settings.ViewDistance, 0.0f, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4(-1.0f));
|
||||
graphics.SetUniform(UniformName.fogsettings, new Vector4f(-1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
974
Source/Core/Rendering/Shaders/ShaderCompiler.cs
Executable file
974
Source/Core/Rendering/Shaders/ShaderCompiler.cs
Executable file
|
@ -0,0 +1,974 @@
|
|||
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<List<ZScriptToken>> ArrayDimensions;
|
||||
public string TypeName;
|
||||
public List<ZScriptToken> Initializer;
|
||||
public string Name;
|
||||
}
|
||||
|
||||
internal class ShaderFunction
|
||||
{
|
||||
public int Line;
|
||||
public int CodeLine;
|
||||
public string ReturnValue;
|
||||
public string Name;
|
||||
public bool Override;
|
||||
public List<ZScriptToken> Arguments;
|
||||
public List<ZScriptToken> Code;
|
||||
}
|
||||
|
||||
class Shader
|
||||
{
|
||||
internal ShaderGroup Group;
|
||||
internal string ParentName;
|
||||
public int CodeLine;
|
||||
public string Name;
|
||||
// data input for vertex shader
|
||||
public List<ShaderField> In;
|
||||
// data between vertex and fragment shader
|
||||
public List<ShaderField> V2F;
|
||||
// data output for fragment shader
|
||||
public List<ShaderField> Out;
|
||||
// source for main() of vertex shader
|
||||
public int SourceVertexLine;
|
||||
public List<ZScriptToken> SourceVertex;
|
||||
// source for main() of fragment shader
|
||||
public int SourceFragmentLine;
|
||||
public List<ZScriptToken> SourceFragment;
|
||||
// functions local to the shader/parents
|
||||
public List<ShaderFunction> Functions = new List<ShaderFunction>();
|
||||
|
||||
private const string GLSLInternalSeparator = "_";
|
||||
|
||||
public Shader(ShaderGroup group)
|
||||
{
|
||||
Group = group;
|
||||
}
|
||||
|
||||
public ShaderFunction GetFunction(string identifier)
|
||||
{
|
||||
foreach (ShaderFunction func in Functions)
|
||||
if (func.Name == identifier)
|
||||
return func;
|
||||
return null;
|
||||
}
|
||||
|
||||
// dumps all uniforms into a string
|
||||
private string GetTokenListSource(List<ZScriptToken> 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<ZScriptToken> 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<ShaderField> 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<ZScriptToken> 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<ZScriptToken> source, List<string> 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 = GetFunction(token.Value);
|
||||
if (func == null) func = Group.GetFunction(token.Value);
|
||||
if (func != null) GetReferencedFunctions(func.Code, functions);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private string GetFunctionSource(List<ZScriptToken> shaderSource)
|
||||
{
|
||||
|
||||
List<string> functionNames = new List<string>();
|
||||
GetReferencedFunctions(shaderSource, functionNames);
|
||||
|
||||
string preOutput = "";
|
||||
string output = "";
|
||||
|
||||
foreach (string functionName in functionNames)
|
||||
{
|
||||
ShaderFunction func = GetFunction(functionName);
|
||||
if (func == null) 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<ZScriptToken> ReplaceIO(List<ZScriptToken> tokens)
|
||||
{
|
||||
|
||||
List<ZScriptToken> output = new List<ZScriptToken>(tokens);
|
||||
|
||||
// we replace all <structPrefix>.<field> with GetDataBlockInternalName(<structPrefix>, <field>)
|
||||
// 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<ShaderField> 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<ShaderField> Uniforms = new List<ShaderField>();
|
||||
internal List<Shader> Shaders = new List<Shader>();
|
||||
internal List<ShaderFunction> Functions = new List<ShaderFunction>();
|
||||
|
||||
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<ZScriptToken> ReadEverythingUntil(ZScriptTokenizer t, ZScriptTokenType type, bool eofIsOk, bool skipWhitespace)
|
||||
{
|
||||
List<ZScriptToken> tokens = new List<ZScriptToken>();
|
||||
|
||||
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 <EOF>", 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() ?? "<EOF>");
|
||||
|
||||
// array finished
|
||||
if (token.Type == ZScriptTokenType.Identifier)
|
||||
{
|
||||
field.Name = token.Value;
|
||||
break;
|
||||
}
|
||||
|
||||
// read array
|
||||
List<ZScriptToken> arrayDimTokens = ReadEverythingUntil(t, ZScriptTokenType.CloseSquare, false, false);
|
||||
if (field.ArrayDimensions == null)
|
||||
field.ArrayDimensions = new List<List<ZScriptToken>>();
|
||||
field.ArrayDimensions.Add(arrayDimTokens);
|
||||
|
||||
token = t.ExpectToken(ZScriptTokenType.CloseSquare);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected closing square brace, got {0}", token?.ToString() ?? "<EOF>");
|
||||
}
|
||||
|
||||
// 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() ?? "<EOF>");
|
||||
|
||||
// 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() ?? "<EOF>");
|
||||
break;
|
||||
}
|
||||
|
||||
// read array
|
||||
List<ZScriptToken> arrayDimTokens = ReadEverythingUntil(t, ZScriptTokenType.CloseSquare, false, false);
|
||||
if (field.ArrayDimensions == null)
|
||||
field.ArrayDimensions = new List<List<ZScriptToken>>();
|
||||
field.ArrayDimensions.Add(arrayDimTokens);
|
||||
|
||||
token = t.ExpectToken(ZScriptTokenType.CloseSquare);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected closing square brace, got {0}", token?.ToString() ?? "<EOF>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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 CompileShaderFunction(ShaderFunction func, ZScriptTokenizer t)
|
||||
{
|
||||
ZScriptToken token;
|
||||
|
||||
t.SkipWhitespace();
|
||||
token = t.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected function name, got {0}", token?.ToString() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
t.SkipWhitespace();
|
||||
token = t.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected function code block, got {0}", token?.ToString() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
}
|
||||
|
||||
private static void CompileFunctions(ShaderGroup output, ZScriptTokenizer t)
|
||||
{
|
||||
|
||||
t.SkipWhitespace();
|
||||
ZScriptToken token;
|
||||
|
||||
token = t.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected functions block, got {0}", token?.ToString() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
if (token.Type == ZScriptTokenType.CloseCurly)
|
||||
break; // done reading functions
|
||||
|
||||
bool isoverride = false;
|
||||
if (token.Value == "override")
|
||||
{
|
||||
isoverride = true;
|
||||
|
||||
t.SkipWhitespace();
|
||||
token = t.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected function return type, got {0}", token?.ToString() ?? "<EOF>");
|
||||
}
|
||||
|
||||
// <return value> <name> (<arguments>) { <code> }
|
||||
ShaderFunction func = new ShaderFunction();
|
||||
func.Line = t.PositionToLine(token.Position);
|
||||
func.ReturnValue = token.Value;
|
||||
func.Override = isoverride;
|
||||
|
||||
CompileShaderFunction(func, t);
|
||||
|
||||
// check if function with such name already exists in the shader
|
||||
// delete it.
|
||||
// overloading is not supported for now
|
||||
for (int i = 0; i < output.Functions.Count; i++)
|
||||
{
|
||||
if (output.Functions[i].Name == func.Name)
|
||||
{
|
||||
if (!isoverride)
|
||||
throw new ShaderCompileException("Function {0} is double-defined without 'override' keyword! (previous declaration at line {1})", func.Name, output.Functions[i].Line);
|
||||
output.Functions.RemoveAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
output.Functions.Add(func);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void CompileShaderFunctions(Shader output, ZScriptTokenizer t)
|
||||
{
|
||||
|
||||
t.SkipWhitespace();
|
||||
ZScriptToken token;
|
||||
|
||||
token = t.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected functions block, got {0}", token?.ToString() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
if (token.Type == ZScriptTokenType.CloseCurly)
|
||||
break; // done reading functions
|
||||
|
||||
bool isoverride = false;
|
||||
if (token.Value == "override")
|
||||
{
|
||||
isoverride = true;
|
||||
|
||||
t.SkipWhitespace();
|
||||
token = t.ExpectToken(ZScriptTokenType.Identifier);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected function return type, got {0}", token?.ToString() ?? "<EOF>");
|
||||
}
|
||||
|
||||
// <return value> <name> (<arguments>) { <code> }
|
||||
ShaderFunction func = new ShaderFunction();
|
||||
func.Line = t.PositionToLine(token.Position);
|
||||
func.ReturnValue = token.Value;
|
||||
func.Override = isoverride;
|
||||
|
||||
CompileShaderFunction(func, t);
|
||||
|
||||
// check if function with such name already exists in the shader
|
||||
// delete it.
|
||||
// overloading is not supported for now
|
||||
if (!isoverride)
|
||||
{
|
||||
ShaderFunction existingFunc = output.Group.GetFunction(func.Name);
|
||||
if (existingFunc != null)
|
||||
throw new ShaderCompileException("Function {0} is double-defined without 'override' keyword! (previous declaration at line {1})", func.Name, existingFunc.Line);
|
||||
}
|
||||
for (int i = 0; i < output.Functions.Count; i++)
|
||||
{
|
||||
if (output.Functions[i].Name == func.Name)
|
||||
{
|
||||
if (!isoverride)
|
||||
throw new ShaderCompileException("Function {0} is double-defined without 'override' keyword! (previous declaration at line {1})", func.Name, output.Functions[i].Line);
|
||||
output.Functions.RemoveAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
output.Functions.Add(func);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<ShaderField> CompileShaderDataBlock(ZScriptTokenizer t)
|
||||
{
|
||||
|
||||
List<ShaderField> fields = new List<ShaderField>();
|
||||
|
||||
t.SkipWhitespace();
|
||||
ZScriptToken token = t.ExpectToken(ZScriptTokenType.OpenCurly);
|
||||
if (!(token?.IsValid ?? true))
|
||||
throw new ShaderCompileException("Expected data block, got {0}", token?.ToString() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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<ZScriptToken> 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() ?? "<EOF>");
|
||||
|
||||
List<ZScriptToken> 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() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
// 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() ?? "<EOF>");
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
}
|
||||
|
||||
|
||||
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() ?? "<EOF>");
|
||||
|
||||
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 "functions":
|
||||
CompileShaderFunctions(s, 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 <name> {}
|
||||
// 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<string> parents = new List<string>();
|
||||
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;
|
||||
}
|
||||
|
||||
// add functions from parent
|
||||
foreach (ShaderFunction func in p.Functions)
|
||||
{
|
||||
if (s.GetFunction(func.Name) == null)
|
||||
s.Functions.Add(func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,15 +6,15 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public struct Vector2
|
||||
public struct Vector2f
|
||||
{
|
||||
public Vector2(float v)
|
||||
public Vector2f(float v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
}
|
||||
|
||||
public Vector2(float x, float y)
|
||||
public Vector2f(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
|
@ -23,7 +23,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
public float X;
|
||||
public float Y;
|
||||
|
||||
public static Vector2 Hermite(Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount)
|
||||
public static Vector2f Hermite(Vector2f value1, Vector2f tangent1, Vector2f value2, Vector2f tangent2, float amount)
|
||||
{
|
||||
float squared = amount * amount;
|
||||
float cubed = amount * squared;
|
||||
|
@ -31,16 +31,16 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
float part2 = (-2.0f * cubed) + (3.0f * squared);
|
||||
float part3 = (cubed - (2.0f * squared)) + amount;
|
||||
float part4 = cubed - squared;
|
||||
return new Vector2(
|
||||
return new Vector2f(
|
||||
(((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4),
|
||||
(((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4));
|
||||
}
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector2)
|
||||
if (o is Vector2f)
|
||||
{
|
||||
Vector2 v = (Vector2)o;
|
||||
Vector2f v = (Vector2f)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
|
@ -54,27 +54,88 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return X.GetHashCode() + Y.GetHashCode();
|
||||
}
|
||||
|
||||
public static Vector2 operator +(Vector2 left, Vector2 right)
|
||||
public static Vector2f operator +(Vector2f left, Vector2f right)
|
||||
{
|
||||
return new Vector2(left.X + right.X, left.Y + right.Y);
|
||||
return new Vector2f(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
public static Vector2 operator -(Vector2 left, Vector2 right)
|
||||
public static Vector2f operator -(Vector2f left, Vector2f right)
|
||||
{
|
||||
return new Vector2(left.X - right.X, left.Y - right.Y);
|
||||
return new Vector2f(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
public static Vector2 operator -(Vector2 v)
|
||||
public static Vector2f operator -(Vector2f v)
|
||||
{
|
||||
return new Vector2(-v.X, -v.Y);
|
||||
return new Vector2f(-v.X, -v.Y);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector2 left, Vector2 right)
|
||||
public static bool operator ==(Vector2f left, Vector2f right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector2 left, Vector2 right)
|
||||
public static bool operator !=(Vector2f left, Vector2f right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Vector2i
|
||||
{
|
||||
public Vector2i(int v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
}
|
||||
|
||||
public Vector2i(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector2i)
|
||||
{
|
||||
Vector2i v = (Vector2i)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode();
|
||||
}
|
||||
|
||||
public static Vector2i operator +(Vector2i left, Vector2i right)
|
||||
{
|
||||
return new Vector2i(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
public static Vector2i operator -(Vector2i left, Vector2i right)
|
||||
{
|
||||
return new Vector2i(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
public static Vector2i operator -(Vector2i v)
|
||||
{
|
||||
return new Vector2i(-v.X, -v.Y);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector2i left, Vector2i right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector2i left, Vector2i right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y;
|
||||
}
|
||||
|
|
|
@ -6,23 +6,23 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public struct Vector3
|
||||
public struct Vector3f
|
||||
{
|
||||
public Vector3(float v)
|
||||
public Vector3f(float v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
Z = v;
|
||||
}
|
||||
|
||||
public Vector3(Vector2 xy, float z)
|
||||
public Vector3f(Vector2f xy, float z)
|
||||
{
|
||||
X = xy.X;
|
||||
Y = xy.Y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public Vector3(float x, float y, float z)
|
||||
public Vector3f(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
|
@ -33,16 +33,16 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
public float Y;
|
||||
public float Z;
|
||||
|
||||
public static Vector4 Transform(Vector3 vector, Matrix transform)
|
||||
public static Vector4f Transform(Vector3f vector, Matrix transform)
|
||||
{
|
||||
return new Vector4(
|
||||
return new Vector4f(
|
||||
(((vector.X * transform.M11) + (vector.Y * transform.M21)) + (vector.Z * transform.M31)) + transform.M41,
|
||||
(((vector.X * transform.M12) + (vector.Y * transform.M22)) + (vector.Z * transform.M32)) + transform.M42,
|
||||
(((vector.X * transform.M13) + (vector.Y * transform.M23)) + (vector.Z * transform.M33)) + transform.M43,
|
||||
(((vector.X * transform.M14) + (vector.Y * transform.M24)) + (vector.Z * transform.M34)) + transform.M44);
|
||||
}
|
||||
|
||||
public static Vector3 Hermite(Vector3 value1, Vector3 tangent1, Vector3 value2, Vector3 tangent2, float amount)
|
||||
public static Vector3f Hermite(Vector3f value1, Vector3f tangent1, Vector3f value2, Vector3f tangent2, float amount)
|
||||
{
|
||||
float squared = amount * amount;
|
||||
float cubed = amount * squared;
|
||||
|
@ -50,26 +50,26 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
float part2 = (-2.0f * cubed) + (3.0f * squared);
|
||||
float part3 = (cubed - (2.0f * squared)) + amount;
|
||||
float part4 = cubed - squared;
|
||||
return new Vector3(
|
||||
return new Vector3f(
|
||||
(((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4),
|
||||
(((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4),
|
||||
(((value1.Z * part1) + (value2.Z * part2)) + (tangent1.Z * part3)) + (tangent2.Z * part4));
|
||||
}
|
||||
|
||||
public static float DistanceSquared(Vector3 a, Vector3 b)
|
||||
public static float DistanceSquared(Vector3f a, Vector3f b)
|
||||
{
|
||||
Vector3 c = b - a;
|
||||
return Vector3.Dot(c, c);
|
||||
Vector3f c = b - a;
|
||||
return Vector3f.Dot(c, c);
|
||||
}
|
||||
|
||||
public static float Dot(Vector3 a, Vector3 b)
|
||||
public static float Dot(Vector3f a, Vector3f b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||
}
|
||||
|
||||
public static Vector3 Cross(Vector3 left, Vector3 right)
|
||||
public static Vector3f Cross(Vector3f left, Vector3f right)
|
||||
{
|
||||
Vector3 result = new Vector3();
|
||||
Vector3f result = new Vector3f();
|
||||
result.X = left.Y * right.Z - left.Z * right.Y;
|
||||
result.Y = left.Z * right.X - left.X * right.Z;
|
||||
result.Z = left.X * right.Y - left.Y * right.X;
|
||||
|
@ -78,10 +78,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
public float Length()
|
||||
{
|
||||
return (float)Math.Sqrt(Vector3.Dot(this, this));
|
||||
return (float)Math.Sqrt(Vector3f.Dot(this, this));
|
||||
}
|
||||
|
||||
public static Vector3 Normalize(Vector3 v)
|
||||
public static Vector3f Normalize(Vector3f v)
|
||||
{
|
||||
v.Normalize();
|
||||
return v;
|
||||
|
@ -100,9 +100,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector3)
|
||||
if (o is Vector3f)
|
||||
{
|
||||
Vector3 v = (Vector3)o;
|
||||
Vector3f v = (Vector3f)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
|
@ -116,27 +116,98 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode();
|
||||
}
|
||||
|
||||
public static Vector3 operator +(Vector3 left, Vector3 right)
|
||||
public static Vector3f operator +(Vector3f left, Vector3f right)
|
||||
{
|
||||
return new Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
return new Vector3f(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 left, Vector3 right)
|
||||
public static Vector3f operator -(Vector3f left, Vector3f right)
|
||||
{
|
||||
return new Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
return new Vector3f(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 v)
|
||||
public static Vector3f operator -(Vector3f v)
|
||||
{
|
||||
return new Vector3(-v.X, -v.Y, -v.Z);
|
||||
return new Vector3f(-v.X, -v.Y, -v.Z);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector3 left, Vector3 right)
|
||||
public static bool operator ==(Vector3f left, Vector3f right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector3 left, Vector3 right)
|
||||
public static bool operator !=(Vector3f left, Vector3f right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Vector3i
|
||||
{
|
||||
public Vector3i(int v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
Z = v;
|
||||
}
|
||||
|
||||
public Vector3i(Vector2i xy, int z)
|
||||
{
|
||||
X = xy.X;
|
||||
Y = xy.Y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public Vector3i(int x, int y, int z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public int X;
|
||||
public int Y;
|
||||
public int Z;
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector3i)
|
||||
{
|
||||
Vector3i v = (Vector3i)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode();
|
||||
}
|
||||
|
||||
public static Vector3i operator +(Vector3i left, Vector3i right)
|
||||
{
|
||||
return new Vector3i(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
public static Vector3i operator -(Vector3i left, Vector3i right)
|
||||
{
|
||||
return new Vector3i(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
}
|
||||
|
||||
public static Vector3i operator -(Vector3i v)
|
||||
{
|
||||
return new Vector3i(-v.X, -v.Y, -v.Z);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector3i left, Vector3i right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector3i left, Vector3i right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public struct Vector4
|
||||
public struct Vector4f
|
||||
{
|
||||
public Vector4(float v)
|
||||
public Vector4f(float v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
|
@ -16,7 +16,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
W = v;
|
||||
}
|
||||
|
||||
public Vector4(Vector2 xy, float z, float w)
|
||||
public Vector4f(Vector2f xy, float z, float w)
|
||||
{
|
||||
X = xy.X;
|
||||
Y = xy.Y;
|
||||
|
@ -24,7 +24,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
W = w;
|
||||
}
|
||||
|
||||
public Vector4(Vector3 xyz, float w)
|
||||
public Vector4f(Vector3f xyz, float w)
|
||||
{
|
||||
X = xyz.X;
|
||||
Y = xyz.Y;
|
||||
|
@ -32,7 +32,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
W = w;
|
||||
}
|
||||
|
||||
public Vector4(float x, float y, float z, float w)
|
||||
public Vector4f(float x, float y, float z, float w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
|
@ -47,9 +47,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector4)
|
||||
if (o is Vector4f)
|
||||
{
|
||||
Vector4 v = (Vector4)o;
|
||||
Vector4f v = (Vector4f)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
|
@ -58,19 +58,19 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
public static Vector4 operator +(Vector4 left, Vector4 right)
|
||||
public static Vector4f operator +(Vector4f left, Vector4f right)
|
||||
{
|
||||
return new Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
return new Vector4f(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 left, Vector4 right)
|
||||
public static Vector4f operator -(Vector4f left, Vector4f right)
|
||||
{
|
||||
return new Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
return new Vector4f(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 v)
|
||||
public static Vector4f operator -(Vector4f v)
|
||||
{
|
||||
return new Vector4(-v.X, -v.Y, -v.Z, -v.W);
|
||||
return new Vector4f(-v.X, -v.Y, -v.Z, -v.W);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
@ -78,12 +78,95 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector4 left, Vector4 right)
|
||||
public static bool operator ==(Vector4f left, Vector4f right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector4 left, Vector4 right)
|
||||
public static bool operator !=(Vector4f left, Vector4f right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Vector4i
|
||||
{
|
||||
public Vector4i(int v)
|
||||
{
|
||||
X = v;
|
||||
Y = v;
|
||||
Z = v;
|
||||
W = v;
|
||||
}
|
||||
|
||||
public Vector4i(Vector2i xy, int z, int w)
|
||||
{
|
||||
X = xy.X;
|
||||
Y = xy.Y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public Vector4i(Vector3i xyz, int w)
|
||||
{
|
||||
X = xyz.X;
|
||||
Y = xyz.Y;
|
||||
Z = xyz.Z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public Vector4i(int x, int y, int z, int w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public int X;
|
||||
public int Y;
|
||||
public int Z;
|
||||
public int W;
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if (o is Vector4i)
|
||||
{
|
||||
Vector4i v = (Vector4i)o;
|
||||
return this == v;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector4i operator +(Vector4i left, Vector4i right)
|
||||
{
|
||||
return new Vector4i(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
public static Vector4i operator -(Vector4i left, Vector4i right)
|
||||
{
|
||||
return new Vector4i(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
public static Vector4i operator -(Vector4i v)
|
||||
{
|
||||
return new Vector4i(-v.X, -v.Y, -v.Z, -v.W);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector4i left, Vector4i right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector4i left, Vector4i right)
|
||||
{
|
||||
return left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W;
|
||||
}
|
||||
|
|
118
Source/Core/Resources/display2d.shader
Executable file
118
Source/Core/Resources/display2d.shader
Executable file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
105
Source/Core/Resources/things2d.shader
Executable file
105
Source/Core/Resources/things2d.shader
Executable file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
373
Source/Core/Resources/world3d.shader
Executable file
373
Source/Core/Resources/world3d.shader
Executable file
|
@ -0,0 +1,373 @@
|
|||
uniforms
|
||||
{
|
||||
mat4 world;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
mat4 modelnormal;
|
||||
vec4 campos;
|
||||
|
||||
vec4 highlightcolor;
|
||||
vec4 stencilColor;
|
||||
float desaturation;
|
||||
|
||||
vec4 fogsettings;
|
||||
vec4 fogcolor;
|
||||
vec4 sectorfogcolor;
|
||||
vec4 vertexColor;
|
||||
|
||||
sampler2D texture1;
|
||||
|
||||
// dynamic light related
|
||||
vec4 lightPosAndRadius[64];
|
||||
vec4 lightOrientation[64]; // this is a vector that points in light's direction
|
||||
vec2 light2Radius[64]; // this is used with spotlights
|
||||
vec4 lightColor[64];
|
||||
float ignoreNormals;
|
||||
float lightsEnabled;
|
||||
|
||||
// Slope handle length
|
||||
float slopeHandleLength;
|
||||
|
||||
}
|
||||
|
||||
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(sectorfogcolor.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);
|
||||
}
|
||||
|
||||
vec3 getOneDynLightContribution(vec3 PosW, vec3 Normal, vec3 light, vec4 lColor, vec4 lPosAndRadius, vec4 lOrientation, vec2 l2Radius)
|
||||
{
|
||||
|
||||
//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(lPosAndRadius.xyz - PosW + Normal * 3.0));
|
||||
if (diffuseContribution < 0.0 && (ignoreNormals == 0 || (lColor.a > 0.979 && lColor.a < 0.981))) // attenuated light and facing away
|
||||
return light;
|
||||
|
||||
diffuseContribution = max(diffuseContribution, 0.0); // to make sure
|
||||
|
||||
//is pixel in light range?
|
||||
float dist = distance(PosW, lPosAndRadius.xyz);
|
||||
|
||||
if (dist > lPosAndRadius.w)
|
||||
return light;
|
||||
|
||||
float power = 1.0;
|
||||
power *= max(lPosAndRadius.w - dist, 0.0) / lPosAndRadius.w;
|
||||
|
||||
if (lOrientation.w > 0.5)
|
||||
{
|
||||
vec3 lightDirection = normalize(lPosAndRadius.xyz - PosW);
|
||||
float cosDir = dot(lightDirection, lOrientation.xyz);
|
||||
float df = smoothstep(l2Radius.y, l2Radius.x, cosDir);
|
||||
power *= df;
|
||||
}
|
||||
|
||||
if (lColor.a > 0.979 && lColor.a < 0.981) // attenuated light 98%
|
||||
power *= diffuseContribution;
|
||||
|
||||
// for w/e reason GZDoom also does this
|
||||
power *= lColor.a;
|
||||
|
||||
if (lColor.a >= 1)
|
||||
return light.rgb - lColor.rgb * power;
|
||||
|
||||
return light.rgb + lColor.rgb * power;
|
||||
|
||||
}
|
||||
|
||||
vec4 getDynLightContribution(vec4 tcolor, vec4 baselight, vec3 PosW, vec3 Normal)
|
||||
{
|
||||
vec3 light = vec3(0, 0, 0);
|
||||
vec3 addlight = vec3(0, 0, 0);
|
||||
|
||||
if (lightsEnabled != 0)
|
||||
{
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (lightColor[i].a == 0)
|
||||
break;
|
||||
if (lightColor[i].a < 0.4) // additive
|
||||
addlight = getOneDynLightContribution(PosW, Normal, addlight, lightColor[i], lightPosAndRadius[i], lightOrientation[i], light2Radius[i]);
|
||||
else light = getOneDynLightContribution(PosW, Normal, light, lightColor[i], lightPosAndRadius[i], lightOrientation[i], light2Radius[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(tcolor.rgb*(baselight.rgb+light)+addlight, tcolor.a*baselight.a);
|
||||
}
|
||||
}
|
||||
|
||||
shader world3d_main
|
||||
{
|
||||
in
|
||||
{
|
||||
vec3 Position;
|
||||
vec4 Color;
|
||||
vec2 TextureCoordinate;
|
||||
vec3 Normal;
|
||||
}
|
||||
|
||||
v2f
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 UV;
|
||||
vec3 PosW;
|
||||
vec3 Normal;
|
||||
vec4 viewpos;
|
||||
}
|
||||
|
||||
out
|
||||
{
|
||||
vec4 FragColor;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
vec4 tcolor = texture(texture1, v2f.UV);
|
||||
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
||||
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
||||
out.FragColor = desaturate(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_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);
|
||||
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
||||
if (tcolor.a == 0.0)
|
||||
{
|
||||
out.FragColor = tcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blend texture color and vertex color
|
||||
vec4 ncolor = desaturate(tcolor);
|
||||
|
||||
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_main_fog extends world3d_main
|
||||
{
|
||||
fragment
|
||||
{
|
||||
vec4 tcolor = texture(texture1, v2f.UV);
|
||||
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
||||
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
||||
if (tcolor.a == 0.0)
|
||||
{
|
||||
out.FragColor = tcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.FragColor = desaturate(getFogColor(v2f.PosW, 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_fog extends world3d_main_fog
|
||||
{
|
||||
fragment
|
||||
{
|
||||
vec4 tcolor = texture(texture1, v2f.UV);
|
||||
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
||||
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
||||
if (tcolor.a == 0.0)
|
||||
{
|
||||
out.FragColor = tcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blend texture color and vertex color
|
||||
vec4 ncolor = desaturate(getFogColor(v2f.PosW, tcolor));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Slope handle shader
|
||||
shader world3d_slope_handle extends world3d_vertex_color
|
||||
{
|
||||
vertex
|
||||
{
|
||||
v2f.viewpos = view * world * vec4(in.Position.x * slopeHandleLength, in.Position.y, in.Position.z, 1.0);
|
||||
gl_Position = projection * v2f.viewpos;
|
||||
v2f.Color = in.Color * vertexColor;
|
||||
v2f.UV = in.TextureCoordinate;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
59
Source/Core/Resources/world3d_skybox.shader
Executable file
59
Source/Core/Resources/world3d_skybox.shader
Executable file
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -179,8 +179,8 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
WorldVertex p2 = vertices[startindex + 1];
|
||||
WorldVertex p3 = vertices[startindex + 2];
|
||||
|
||||
Vector3 U = new Vector3(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
|
||||
Vector3 V = new Vector3(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z);
|
||||
Vector3f U = new Vector3f(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
|
||||
Vector3f V = new Vector3f(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z);
|
||||
|
||||
p1.nx = p2.nx = p3.nx = -(U.Y * V.Z - U.Z * V.Y);
|
||||
p1.ny = p2.ny = p3.ny = -(U.Z * V.X - U.X * V.Z);
|
||||
|
|
|
@ -109,15 +109,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
public virtual void Update() {}
|
||||
|
||||
public void SetPosition(Vector3D pos, Geometry.Plane plane, float angle)
|
||||
public void SetPosition(Vector3D pos, Plane plane, float angle)
|
||||
{
|
||||
|
||||
Vector3D lookatpoint = new Vector3D(pos.x+128.0f, pos.y+128.0f, plane.GetZ(pos.x + 128.0f, pos.y + 128.0f));
|
||||
Matrix translate = Matrix.Translation(pos.x, pos.y, pos.z);
|
||||
Matrix rotate = Matrix.RotationZ(angle);
|
||||
Vector3 v = new Vector3(plane.Normal.x, plane.Normal.y, plane.Normal.z);
|
||||
Matrix planerotate = Matrix.LookAt(new Vector3f(pos.x, pos.y, pos.z), new Vector3f(lookatpoint.x, lookatpoint.y, lookatpoint.z+0.1f), new Vector3f(0.0f, 1.0f, 0.0f));
|
||||
|
||||
Matrix xrotate = Matrix.RotationX(90.0f);
|
||||
//Vector3 v = new Vector3(plane.Normal.x, plane.Normal.y, plane.Normal.z);
|
||||
// Matrix rotate = Matrix.RotationAxis(v, angle);
|
||||
//position = Matrix.Multiply(rotate, translate);
|
||||
position = Matrix.Multiply(rotate, translate);
|
||||
//position = Matrix.Multiply(translate, planerotate);
|
||||
position = planerotate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Map;
|
|||
using CodeImp.DoomBuilder.Rendering;
|
||||
using Plane = CodeImp.DoomBuilder.Geometry.Plane;
|
||||
using CodeImp.DoomBuilder.GZBuilder;
|
||||
using CodeImp.DoomBuilder.GZBuilder.MD3;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -87,12 +88,12 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
private float lightSpotRadius2;
|
||||
private float lightPrimaryRadius;
|
||||
private float lightSecondaryRadius;
|
||||
private Vector3 position_v3;
|
||||
private Vector3f position_v3;
|
||||
private float lightDelta; //used in light animation
|
||||
private Vector3D[] boundingBox;
|
||||
|
||||
//gldefs light
|
||||
private Vector3 lightOffset;
|
||||
private Vector3f lightOffset;
|
||||
private int lightInterval;
|
||||
private bool isGldefsLight;
|
||||
|
||||
|
@ -116,18 +117,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
internal int VertexColor { get { return vertices.Length > 0 && vertices[0].Length > 0 ? vertices[0][0].c : 0; } }
|
||||
public int CameraDistance { get { return cameradistance; } }
|
||||
public float FogFactor { get { return fogfactor; } }
|
||||
public Vector3 Center
|
||||
public Vector3f Center
|
||||
{
|
||||
get
|
||||
{
|
||||
if (isGldefsLight) return position_v3 + lightOffset;
|
||||
else if (Thing.DynamicLightType != null) return position_v3; // fixes GZDoomBuilder-Bugfix#137
|
||||
return new Vector3(position_v3.X, position_v3.Y, position_v3.Z + thingheight / 2f);
|
||||
return new Vector3f(position_v3.X, position_v3.Y, position_v3.Z + thingheight / 2f);
|
||||
}
|
||||
}
|
||||
public Vector3D CenterV3D { get { return RenderDevice.V3D(Center); } }
|
||||
public float LocalCenterZ { get { return thingheight / 2f; } } //mxd
|
||||
public Vector3 PositionV3 { get { return position_v3; } }
|
||||
public Vector3f PositionV3 { get { return position_v3; } }
|
||||
public Vector3D[] BoundingBox { get { return boundingBox; } }
|
||||
|
||||
//mxd. light properties
|
||||
|
@ -141,12 +142,12 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
public PixelColor StencilColor { get { return stencilColor; } }
|
||||
|
||||
// [ZZ] this is used for spotlights
|
||||
public Vector3 VectorLookAt
|
||||
public Vector3f VectorLookAt
|
||||
{
|
||||
get
|
||||
{
|
||||
// this esoteric value (1.5708) is 90 degrees but in radians
|
||||
return new Vector3((float)(Math.Cos(Thing.Angle+1.5708) * Math.Cos(Angle2D.DegToRad(Thing.Pitch))), (float)(Math.Sin(Thing.Angle+1.5708) * Math.Cos(Angle2D.DegToRad(Thing.Pitch))), (float)Math.Sin(Angle2D.DegToRad(Thing.Pitch)));
|
||||
return new Vector3f((float)(Math.Cos(Thing.Angle+1.5708) * Math.Cos(Angle2D.DegToRad(Thing.Pitch))), (float)(Math.Sin(Thing.Angle+1.5708) * Math.Cos(Angle2D.DegToRad(Thing.Pitch))), (float)Math.Sin(Angle2D.DegToRad(Thing.Pitch)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +358,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
float zoffset = ((thing.Pitch == 0f && thing.Position.z == 0f) ? 0.1f : 0f); // Slight offset to avoid z-fighting...
|
||||
for(int i = 0; i < vertices[c].Length; i++)
|
||||
{
|
||||
Vector4 transformed = Vector3.Transform(new Vector3(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
Vector4f transformed = Vector3f.Transform(new Vector3f(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
vertices[c][i].x = transformed.X;
|
||||
vertices[c][i].y = transformed.Y;
|
||||
vertices[c][i].z = transformed.Z + zoffset;
|
||||
|
@ -385,7 +386,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
// Apply transform
|
||||
for(int i = 0; i < vertices[c].Length; i++)
|
||||
{
|
||||
Vector4 transformed = Vector3.Transform(new Vector3(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
Vector4f transformed = Vector3f.Transform(new Vector3f(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
vertices[c][i].x = transformed.X;
|
||||
vertices[c][i].y = transformed.Y;
|
||||
vertices[c][i].z = transformed.Z;
|
||||
|
@ -496,7 +497,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
// Apply transform
|
||||
for(int i = 0; i < vertices[c].Length; i++)
|
||||
{
|
||||
Vector4 transformed = Vector3.Transform(new Vector3(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
Vector4f transformed = Vector3f.Transform(new Vector3f(vertices[c][i].x, vertices[c][i].y, vertices[c][i].z), transform);
|
||||
vertices[c][i].x = transformed.X;
|
||||
vertices[c][i].y = transformed.Y;
|
||||
vertices[c][i].z = transformed.Z;
|
||||
|
@ -769,7 +770,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
//apply settings
|
||||
lightColor = new Color4(light.Color.Red, light.Color.Green, light.Color.Blue, (float)ld.LightRenderStyle / 100.0f);
|
||||
Vector2D o = new Vector2D(light.Offset.X, light.Offset.Y).GetRotated(thing.Angle - Angle2D.PIHALF);
|
||||
lightOffset = new Vector3(o.x, o.y, light.Offset.Z);
|
||||
lightOffset = new Vector3f(o.x, o.y, light.Offset.Z);
|
||||
lightType = light.Type;
|
||||
|
||||
if(ld.LightModifier == GZGeneral.LightModifier.SECTOR)
|
||||
|
@ -851,17 +852,50 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
{
|
||||
boundingBox = new Vector3D[9];
|
||||
boundingBox[0] = CenterV3D;
|
||||
float h2 = height / 2.0f;
|
||||
|
||||
boundingBox[1] = new Vector3D(position_v3.X - width, position_v3.Y - width, Center.Z - h2);
|
||||
boundingBox[2] = new Vector3D(position_v3.X + width, position_v3.Y - width, Center.Z - h2);
|
||||
boundingBox[3] = new Vector3D(position_v3.X - width, position_v3.Y + width, Center.Z - h2);
|
||||
boundingBox[4] = new Vector3D(position_v3.X + width, position_v3.Y + width, Center.Z - h2);
|
||||
if (Thing.RenderMode != ThingRenderMode.MODEL && Thing.RenderMode != ThingRenderMode.VOXEL)
|
||||
{
|
||||
|
||||
boundingBox[5] = new Vector3D(position_v3.X - width, position_v3.Y - width, Center.Z + h2);
|
||||
boundingBox[6] = new Vector3D(position_v3.X + width, position_v3.Y - width, Center.Z + h2);
|
||||
boundingBox[7] = new Vector3D(position_v3.X - width, position_v3.Y + width, Center.Z + h2);
|
||||
boundingBox[8] = new Vector3D(position_v3.X + width, position_v3.Y + width, Center.Z + h2);
|
||||
float h2 = height / 2.0f;
|
||||
|
||||
boundingBox[1] = new Vector3D(position_v3.X - width, position_v3.Y - width, Center.Z - h2);
|
||||
boundingBox[2] = new Vector3D(position_v3.X + width, position_v3.Y - width, Center.Z - h2);
|
||||
boundingBox[3] = new Vector3D(position_v3.X - width, position_v3.Y + width, Center.Z - h2);
|
||||
boundingBox[4] = new Vector3D(position_v3.X + width, position_v3.Y + width, Center.Z - h2);
|
||||
|
||||
boundingBox[5] = new Vector3D(position_v3.X - width, position_v3.Y - width, Center.Z + h2);
|
||||
boundingBox[6] = new Vector3D(position_v3.X + width, position_v3.Y - width, Center.Z + h2);
|
||||
boundingBox[7] = new Vector3D(position_v3.X - width, position_v3.Y + width, Center.Z + h2);
|
||||
boundingBox[8] = new Vector3D(position_v3.X + width, position_v3.Y + width, Center.Z + h2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
GZModel model = General.Map?.Data?.ModeldefEntries[Thing.Type]?.Model;
|
||||
|
||||
if (model != null)
|
||||
{
|
||||
|
||||
Vector3D offs = new Vector3D(position_v3.X, position_v3.Y, position_v3.Z);
|
||||
|
||||
boundingBox[5] = new Vector3D(model.BBox.MinX, model.BBox.MinY, model.BBox.MaxZ) + offs;
|
||||
boundingBox[6] = new Vector3D(model.BBox.MaxX, model.BBox.MinY, model.BBox.MaxZ) + offs;
|
||||
boundingBox[7] = new Vector3D(model.BBox.MinX, model.BBox.MaxY, model.BBox.MaxZ) + offs;
|
||||
boundingBox[8] = new Vector3D(model.BBox.MaxX, model.BBox.MaxY, model.BBox.MaxZ) + offs;
|
||||
|
||||
boundingBox[1] = new Vector3D(model.BBox.MinX, model.BBox.MinY, model.BBox.MinZ) + offs;
|
||||
boundingBox[2] = new Vector3D(model.BBox.MaxX, model.BBox.MinY, model.BBox.MinZ) + offs;
|
||||
boundingBox[3] = new Vector3D(model.BBox.MinX, model.BBox.MaxY, model.BBox.MinZ) + offs;
|
||||
boundingBox[4] = new Vector3D(model.BBox.MaxX, model.BBox.MaxY, model.BBox.MinZ) + offs;
|
||||
|
||||
boundingBox[0] = new Vector3D(0.5f * (model.BBox.MinX + model.BBox.MaxX),
|
||||
0.5f * (model.BBox.MinY + model.BBox.MaxY),
|
||||
0.5f * (model.BBox.MinZ + model.BBox.MaxZ)) + offs;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. This updates the sprite frame to be rendered
|
||||
|
@ -894,3 +928,4 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
private Dictionary<int, string>[] surfaceskinenames;
|
||||
private string[] modelnames;
|
||||
private string path;
|
||||
private Vector3 scale;
|
||||
private Vector3 offset;
|
||||
private Vector3f scale;
|
||||
private Vector3f offset;
|
||||
private float angleoffset;
|
||||
private float pitchoffset;
|
||||
private float rolloffset;
|
||||
|
@ -55,8 +55,8 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
public string[] SkinNames { get { return skinnames; } }
|
||||
public Dictionary<int, string>[] SurfaceSkinNames { get { return surfaceskinenames; } }
|
||||
public string[] ModelNames { get { return modelnames; } }
|
||||
public Vector3 Scale { get { return scale; } }
|
||||
public Vector3 Offset { get { return offset; } }
|
||||
public Vector3f Scale { get { return scale; } }
|
||||
public Vector3f Offset { get { return offset; } }
|
||||
public float AngleOffset { get { return angleoffset; } }
|
||||
public float PitchOffset { get { return pitchoffset; } }
|
||||
public float RollOffset { get { return rolloffset; } }
|
||||
|
@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
skinnames = new string[MAX_MODELS];
|
||||
modelnames = new string[MAX_MODELS];
|
||||
frames = new Dictionary<string, HashSet<FrameStructure>>(StringComparer.OrdinalIgnoreCase);
|
||||
scale = new Vector3(1.0f, 1.0f, 1.0f);
|
||||
scale = new Vector3f(1.0f, 1.0f, 1.0f);
|
||||
surfaceskinenames = new Dictionary<int, string>[MAX_MODELS];
|
||||
for(int i = 0; i < MAX_MODELS; i++)
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace CodeImp.DoomBuilder.ZDoom
|
|||
if(!string.IsNullOrEmpty(modelName) && spriteNames.Count > 0)
|
||||
{
|
||||
mde.ModelNames.Add(modelName);
|
||||
mde.SetTransform(Matrix.RotationZ(Angle2D.DegToRad(mde.AngleOffset)), Matrix.Identity, new Vector3(scale));
|
||||
mde.SetTransform(Matrix.RotationZ(Angle2D.DegToRad(mde.AngleOffset)), Matrix.Identity, new Vector3f(scale));
|
||||
|
||||
foreach(string s in spriteNames)
|
||||
{
|
||||
|
|
|
@ -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<long> LinePositions;
|
||||
|
||||
public ZScriptTokenizer(BinaryReader br)
|
||||
{
|
||||
reader = br;
|
||||
|
||||
long cpos = br.BaseStream.Position;
|
||||
LinePositions = new List<long>();
|
||||
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;
|
||||
|
@ -542,6 +582,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;
|
||||
|
|
|
@ -23,6 +23,33 @@
|
|||
#include "Backend.h"
|
||||
#include "OpenGL/GLBackend.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string mLastError;
|
||||
std::string mReturnError;
|
||||
char mSetErrorBuffer[4096];
|
||||
}
|
||||
|
||||
void SetError(const char* fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
mSetErrorBuffer[0] = 0;
|
||||
_vsnprintf(mSetErrorBuffer, sizeof(mSetErrorBuffer) - 1, fmt, va);
|
||||
va_end(va);
|
||||
mSetErrorBuffer[sizeof(mSetErrorBuffer) - 1] = 0;
|
||||
mLastError = mSetErrorBuffer;
|
||||
}
|
||||
|
||||
const char* GetError()
|
||||
{
|
||||
mReturnError.swap(mLastError);
|
||||
mLastError.clear();
|
||||
return mReturnError.c_str();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Backend* Backend::Get()
|
||||
{
|
||||
static std::unique_ptr<Backend> backend;
|
||||
|
@ -45,9 +72,9 @@ extern "C"
|
|||
Backend::Get()->DeleteRenderDevice(device);
|
||||
}
|
||||
|
||||
const char* RenderDevice_GetError(RenderDevice* device)
|
||||
const char* BuilderNative_GetError()
|
||||
{
|
||||
return device->GetError();
|
||||
return GetError();
|
||||
}
|
||||
|
||||
void RenderDevice_DeclareUniform(RenderDevice* device, UniformName name, const char* variablename, UniformType type)
|
||||
|
@ -65,9 +92,9 @@ extern "C"
|
|||
device->SetShader(name);
|
||||
}
|
||||
|
||||
void RenderDevice_SetUniform(RenderDevice* device, UniformName name, const void* values, int count)
|
||||
void RenderDevice_SetUniform(RenderDevice* device, UniformName name, const void* values, int count, int bytesize)
|
||||
{
|
||||
device->SetUniform(name, values, count);
|
||||
device->SetUniform(name, values, count, bytesize);
|
||||
}
|
||||
|
||||
void RenderDevice_SetVertexBuffer(RenderDevice* device, VertexBuffer* buffer)
|
||||
|
|
|
@ -37,7 +37,7 @@ enum class ShaderFlags : int { None, Debug };
|
|||
enum class PrimitiveType : int { LineList, TriangleList, TriangleStrip };
|
||||
enum class TextureFilter : int { Nearest, Linear };
|
||||
enum class MipmapFilter : int { None, Nearest, Linear };
|
||||
enum class UniformType : int { Vec4f, Vec3f, Vec2f, Float, Mat4 };
|
||||
enum class UniformType : int { Vec4f, Vec3f, Vec2f, Float, Mat4, Vec4i, Vec3i, Vec2i, Int, Vec4fArray, Vec3fArray, Vec2fArray };
|
||||
|
||||
typedef int UniformName;
|
||||
typedef int ShaderName;
|
||||
|
@ -51,12 +51,10 @@ class RenderDevice
|
|||
public:
|
||||
virtual ~RenderDevice() = default;
|
||||
|
||||
virtual const char* GetError() = 0;
|
||||
|
||||
virtual void DeclareUniform(UniformName name, const char* glslname, UniformType type) = 0;
|
||||
virtual void DeclareShader(ShaderName index, const char* name, const char* vertexshader, const char* fragmentshader) = 0;
|
||||
virtual void SetShader(ShaderName name) = 0;
|
||||
virtual void SetUniform(UniformName name, const void* values, int count) = 0;
|
||||
virtual void SetUniform(UniformName name, const void* values, int count, int bytesize) = 0;
|
||||
virtual void SetVertexBuffer(VertexBuffer* buffer) = 0;
|
||||
virtual void SetIndexBuffer(IndexBuffer* buffer) = 0;
|
||||
virtual void SetAlphaBlendEnable(bool value) = 0;
|
||||
|
@ -129,3 +127,6 @@ public:
|
|||
virtual Texture* NewTexture() = 0;
|
||||
virtual void DeleteTexture(Texture* texture) = 0;
|
||||
};
|
||||
|
||||
void SetError(const char* fmt, ...);
|
||||
const char* GetError();
|
||||
|
|
|
@ -679,24 +679,6 @@ bool GLRenderDevice::CheckGLError()
|
|||
return false;
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetError(const char* fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
mSetErrorBuffer[0] = 0;
|
||||
mSetErrorBuffer[sizeof(mSetErrorBuffer) - 1] = 0;
|
||||
_vsnprintf(mSetErrorBuffer, sizeof(mSetErrorBuffer)-1, fmt, va);
|
||||
va_end(va);
|
||||
mLastError = mSetErrorBuffer;
|
||||
}
|
||||
|
||||
const char* GLRenderDevice::GetError()
|
||||
{
|
||||
mReturnError.swap(mLastError);
|
||||
mLastError.clear();
|
||||
return mReturnError.c_str();
|
||||
}
|
||||
|
||||
GLShader* GLRenderDevice::GetActiveShader()
|
||||
{
|
||||
if (mAlphaTest)
|
||||
|
@ -716,12 +698,16 @@ void GLRenderDevice::SetShader(ShaderName name)
|
|||
}
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetUniform(UniformName name, const void* values, int count)
|
||||
void GLRenderDevice::SetUniform(UniformName name, const void* values, int count, int bytesize)
|
||||
{
|
||||
float* dest = mUniformData.data() + mUniformInfo[(int)name].Offset;
|
||||
if (memcmp(dest, values, sizeof(float) * count) != 0)
|
||||
// "count" should be in bytes now
|
||||
UniformInfo& info = mUniformInfo[(int)name];
|
||||
info.Count = count;
|
||||
info.Data.resize(bytesize);
|
||||
uint8_t* dest = info.Data.data();
|
||||
if (memcmp(dest, values, bytesize) != 0)
|
||||
{
|
||||
memcpy(dest, values, sizeof(float) * count);
|
||||
memcpy(dest, values, bytesize);
|
||||
mUniformInfo[(int)name].LastUpdate++;
|
||||
mNeedApply = true;
|
||||
mUniformsChanged = true;
|
||||
|
@ -858,9 +844,6 @@ void GLRenderDevice::DeclareUniform(UniformName name, const char* glslname, Unif
|
|||
UniformInfo& info = mUniformInfo[index];
|
||||
info.Name = glslname;
|
||||
info.Type = type;
|
||||
info.Offset = (int)mUniformData.size();
|
||||
|
||||
mUniformData.resize(mUniformData.size() + (type == UniformType::Mat4 ? 16 : 4));
|
||||
}
|
||||
|
||||
bool GLRenderDevice::ApplyUniforms()
|
||||
|
@ -872,18 +855,27 @@ bool GLRenderDevice::ApplyUniforms()
|
|||
int count = (int)mUniformInfo.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (lastupdates[i] != mUniformInfo.data()[i].LastUpdate)
|
||||
UniformInfo& info = mUniformInfo.data()[i];
|
||||
if (lastupdates[i] != info.LastUpdate)
|
||||
{
|
||||
float* data = mUniformData.data() + mUniformInfo[i].Offset;
|
||||
float* data = (float*)info.Data.data();
|
||||
int* idata = (int*)info.Data.data();
|
||||
GLuint location = locations[i];
|
||||
switch (mUniformInfo[i].Type)
|
||||
{
|
||||
default:
|
||||
default: break;
|
||||
case UniformType::Vec4f: glUniform4fv(location, 1, data); break;
|
||||
case UniformType::Vec3f: glUniform3fv(location, 1, data); break;
|
||||
case UniformType::Vec2f: glUniform2fv(location, 1, data); break;
|
||||
case UniformType::Float: glUniform1fv(location, 1, data); break;
|
||||
case UniformType::Mat4: glUniformMatrix4fv(location, 1, GL_FALSE, data); break;
|
||||
case UniformType::Vec4i: glUniform4iv(location, 1, idata); break;
|
||||
case UniformType::Vec3i: glUniform3iv(location, 1, idata); break;
|
||||
case UniformType::Vec2i: glUniform2iv(location, 1, idata); break;
|
||||
case UniformType::Int: glUniform1iv(location, 1, idata); break;
|
||||
case UniformType::Vec4fArray: glUniform4fv(location, info.Count, data); break;
|
||||
case UniformType::Vec3fArray: glUniform3fv(location, info.Count, data); break;
|
||||
case UniformType::Vec2fArray: glUniform2fv(location, info.Count, data); break;
|
||||
}
|
||||
lastupdates[i] = mUniformInfo[i].LastUpdate;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
void DeclareUniform(UniformName name, const char* glslname, UniformType type) override;
|
||||
void DeclareShader(ShaderName index, const char* name, const char* vertexshader, const char* fragmentshader) override;
|
||||
void SetShader(ShaderName name) override;
|
||||
void SetUniform(UniformName name, const void* values, int count) override;
|
||||
void SetUniform(UniformName name, const void* values, int count, int bytesize) override;
|
||||
void SetVertexBuffer(VertexBuffer* buffer) override;
|
||||
void SetIndexBuffer(IndexBuffer* buffer) override;
|
||||
void SetAlphaBlendEnable(bool value) override;
|
||||
|
@ -94,8 +94,6 @@ public:
|
|||
void RequireContext();
|
||||
|
||||
bool CheckGLError();
|
||||
void SetError(const char* fmt, ...);
|
||||
const char* GetError();
|
||||
|
||||
GLShader* GetActiveShader();
|
||||
|
||||
|
@ -161,12 +159,12 @@ public:
|
|||
{
|
||||
std::string Name;
|
||||
UniformType Type = {};
|
||||
int Offset = 0;
|
||||
int LastUpdate = 0;
|
||||
int Count = 0;
|
||||
std::vector<uint8_t> Data;
|
||||
};
|
||||
|
||||
std::vector<UniformInfo> mUniformInfo;
|
||||
std::vector<float> mUniformData;
|
||||
|
||||
GLuint mStreamVertexBuffer = 0;
|
||||
GLuint mStreamVAO = 0;
|
||||
|
@ -195,10 +193,6 @@ public:
|
|||
|
||||
bool mContextIsCurrent = false;
|
||||
|
||||
std::string mLastError;
|
||||
std::string mReturnError;
|
||||
char mSetErrorBuffer[4096];
|
||||
|
||||
int mViewportWidth = 0;
|
||||
int mViewportHeight = 0;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
)";
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "Precomp.h"
|
||||
#include "OpenGLContext.h"
|
||||
#include "../Backend.h"
|
||||
#include <stdexcept>
|
||||
|
||||
class OpenGLLoadFunctions
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
OpenGLCreationHelper(HWND window);
|
||||
~OpenGLCreationHelper();
|
||||
|
||||
HGLRC CreateContext(HDC hdc, int major_version, int minor_version, HGLRC share_context = 0);
|
||||
HGLRC CreateContext(HDC hdc, HGLRC share_context = 0);
|
||||
|
||||
private:
|
||||
HWND window;
|
||||
|
@ -142,7 +143,7 @@ OpenGLContext::OpenGLContext(void* windowptr) : window((HWND)windowptr)
|
|||
{
|
||||
dc = GetDC(window);
|
||||
OpenGLCreationHelper helper(window);
|
||||
context = helper.CreateContext(dc, 3, 2);
|
||||
context = helper.CreateContext(dc);
|
||||
if (context)
|
||||
{
|
||||
MakeCurrent();
|
||||
|
@ -229,9 +230,11 @@ OpenGLCreationHelper::OpenGLCreationHelper(HWND window) : window(window)
|
|||
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cDepthBits = 16;
|
||||
pfd.cStencilBits = 8;
|
||||
|
||||
int pixelformat = ChoosePixelFormat(query_dc, &pfd);
|
||||
SetPixelFormat(query_dc, pixelformat, &pfd);
|
||||
|
@ -253,7 +256,7 @@ OpenGLCreationHelper::~OpenGLCreationHelper()
|
|||
DestroyWindow(query_window);
|
||||
}
|
||||
|
||||
HGLRC OpenGLCreationHelper::CreateContext(HDC hdc, int major_version, int minor_version, HGLRC share_context)
|
||||
HGLRC OpenGLCreationHelper::CreateContext(HDC hdc, HGLRC share_context)
|
||||
{
|
||||
if (query_context == 0)
|
||||
return 0;
|
||||
|
@ -264,13 +267,10 @@ HGLRC OpenGLCreationHelper::CreateContext(HDC hdc, int major_version, int minor_
|
|||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cRedBits = 8;
|
||||
pfd.cGreenBits = 8;
|
||||
pfd.cBlueBits = 8;
|
||||
pfd.cAlphaBits = 8;
|
||||
pfd.cDepthBits = 24;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cDepthBits = 16;
|
||||
pfd.cStencilBits = 8;
|
||||
|
||||
int pixelformat = ChoosePixelFormat(hdc, &pfd);
|
||||
SetPixelFormat(hdc, pixelformat, &pfd);
|
||||
|
||||
|
@ -278,25 +278,43 @@ HGLRC OpenGLCreationHelper::CreateContext(HDC hdc, int major_version, int minor_
|
|||
|
||||
ptr_wglCreateContextAttribsARB wglCreateContextAttribsARB = (ptr_wglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
|
||||
typedef GLenum(WINAPI* glErrorPtr)();
|
||||
glErrorPtr error = reinterpret_cast<glErrorPtr>(GetProcAddress(LoadLibrary("opengl32.dll"), "glGetError"));
|
||||
|
||||
HGLRC opengl3_context = 0;
|
||||
if (wglCreateContextAttribsARB)
|
||||
{
|
||||
std::vector<int> int_attributes;
|
||||
for (int profile : { 1/*WGL_CONTEXT_CORE_PROFILE_BIT_ARB*/, 2 /*WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB*/ })
|
||||
{
|
||||
for (int version : { 46, 45, 44, 43, 42, 41, 40, 33, 32 })
|
||||
{
|
||||
std::vector<int> int_attributes;
|
||||
int_attributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
|
||||
int_attributes.push_back(version / 10);
|
||||
int_attributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
|
||||
int_attributes.push_back(version % 10);
|
||||
int_attributes.push_back(0x9126); // WGL_CONTEXT_PROFILE_MASK_ARB
|
||||
int_attributes.push_back(profile);
|
||||
int_attributes.push_back(0);
|
||||
opengl3_context = wglCreateContextAttribsARB(hdc, share_context, int_attributes.data());
|
||||
|
||||
int_attributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
|
||||
int_attributes.push_back(major_version);
|
||||
int_attributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
|
||||
int_attributes.push_back(minor_version);
|
||||
if (opengl3_context)
|
||||
break;
|
||||
}
|
||||
|
||||
int_attributes.push_back(0x2094); // WGL_CONTEXT_FLAGS_ARB
|
||||
int_attributes.push_back(0x2); // WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
||||
if (opengl3_context)
|
||||
break;
|
||||
}
|
||||
|
||||
int_attributes.push_back(0x9126); // WGL_CONTEXT_PROFILE_MASK_ARB
|
||||
int_attributes.push_back(0x1); // WGL_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||
|
||||
int_attributes.push_back(0);
|
||||
|
||||
opengl3_context = wglCreateContextAttribsARB(hdc, share_context, int_attributes.data());
|
||||
// Grab the error from the last create attempt
|
||||
if (!opengl3_context)
|
||||
{
|
||||
SetError("No OpenGL 3.2 support found (error code %d)", (int)error());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError("No OpenGL driver supporting OpenGL 3 found");
|
||||
}
|
||||
|
||||
wglMakeCurrent(0, 0);
|
||||
|
@ -809,32 +827,36 @@ GLXContext OpenGLContext::create_context_glx_1_3(GLXContext shared_context)
|
|||
// threads issuing X commands while this code is running.
|
||||
int (*oldHandler)(::Display*, XErrorEvent*) = XSetErrorHandler(&cl_ctxErrorHandler);
|
||||
|
||||
std::vector<int> int_attributes;
|
||||
|
||||
int_attributes.push_back(0x2091); // GLX_CONTEXT_MAJOR_VERSION_ARB
|
||||
int_attributes.push_back(major_version);
|
||||
int_attributes.push_back(0x2092); // GLX_CONTEXT_MINOR_VERSION_ARB
|
||||
int_attributes.push_back(minor_version);
|
||||
|
||||
int_attributes.push_back(0x2094); // GLX_CONTEXT_FLAGS_ARB
|
||||
int_attributes.push_back(0x2); // GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
||||
|
||||
int_attributes.push_back(0x9126); // GLX_CONTEXT_PROFILE_MASK_ARB
|
||||
int_attributes.push_back(0x1); // GLX_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||
|
||||
int_attributes.push_back(None);
|
||||
|
||||
cl_ctxErrorOccurred = false;
|
||||
|
||||
GLXContext context_gl3 = glXCreateContextAttribs(disp, fbconfig, shared_context, True, &int_attributes[0]);
|
||||
|
||||
if (cl_ctxErrorOccurred)
|
||||
GLXContext context_gl3 = 0;
|
||||
for (int profile : { 1/*GLX_CONTEXT_CORE_PROFILE_BIT_ARB*/, 2 /*GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB*/ })
|
||||
{
|
||||
if (context_gl3)
|
||||
for (int version : { 46, 45, 44, 43, 42, 41, 40, 33, 32 })
|
||||
{
|
||||
glx.glXDestroyContext(disp, context_gl3);
|
||||
context_gl3 = nullptr;
|
||||
std::vector<int> int_attributes;
|
||||
int_attributes.push_back(0x2091); // GLX_CONTEXT_MAJOR_VERSION_ARB
|
||||
int_attributes.push_back(version / 10);
|
||||
int_attributes.push_back(0x2092); // GLX_CONTEXT_MINOR_VERSION_ARB
|
||||
int_attributes.push_back(version % 10);
|
||||
int_attributes.push_back(0x9126); // GLX_CONTEXT_PROFILE_MASK_ARB
|
||||
int_attributes.push_back(profile);
|
||||
int_attributes.push_back(None);
|
||||
|
||||
cl_ctxErrorOccurred = false;
|
||||
|
||||
context_gl3 = glXCreateContextAttribs(disp, fbconfig, shared_context, True, int_attributes.data());
|
||||
|
||||
if (cl_ctxErrorOccurred && context_gl3)
|
||||
{
|
||||
glx.glXDestroyContext(disp, context_gl3);
|
||||
context_gl3 = nullptr;
|
||||
}
|
||||
|
||||
if (context_gl3)
|
||||
break;
|
||||
}
|
||||
|
||||
if (context_gl3)
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore the original error handler
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
EXPORTS
|
||||
|
||||
BuilderNative_GetError
|
||||
RenderDevice_New
|
||||
RenderDevice_Delete
|
||||
RenderDevice_GetError
|
||||
RenderDevice_DeclareUniform
|
||||
RenderDevice_DeclareShader
|
||||
RenderDevice_SetShader
|
||||
|
|
|
@ -4332,7 +4332,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
float offset;
|
||||
|
||||
if (!texture.WorldPanning && !General.Map.Data.MapInfo.ForceWorldPanning)
|
||||
offset = ((start.Sidedef.Sector.CeilHeight - j.ceilingHeight) / scaley) * j.scaleY + ystartalign - j.sidedef.OffsetY; //mxd
|
||||
offset = ((start.Sidedef.Sector.CeilHeight - j.ceilingHeight) / scaley) * Math.Abs(j.scaleY) + ystartalign - j.sidedef.OffsetY; //mxd
|
||||
else
|
||||
offset = (start.Sidedef.Sector.CeilHeight - j.ceilingHeight + ystartalign - j.sidedef.OffsetY);
|
||||
|
||||
|
@ -4474,7 +4474,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
if(aligny)
|
||||
{
|
||||
float offset = ((start.Sidedef.Sector.CeilHeight - j.ceilingHeight) / scaley) * j.scaleY + ystartalign; //mxd
|
||||
float offset = ((start.Sidedef.Sector.CeilHeight - j.ceilingHeight) / scaley) * Math.Abs(j.scaleY) + ystartalign; //mxd
|
||||
offset -= j.sidedef.OffsetY; //mxd
|
||||
|
||||
if(matchtop)
|
||||
|
|
Loading…
Reference in a new issue