mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-25 05:11:56 +00:00
New feature: classic lighting renderer for visual mode (#680)
Added classic rendering mode to closer emulate software renderer visuals in visual mode
This commit is contained in:
parent
90896acd43
commit
7fbd07e586
32 changed files with 1039 additions and 414 deletions
|
@ -4,4 +4,6 @@
|
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UDMF/@EntryIndexedValue">UDMF</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/CheckedGroups/=Builder_002FProperties_002FResources/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/ResxEditorPersonal/Initialized/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
|
|
@ -209,6 +209,7 @@
|
|||
<Compile Include="Controls\Scripting\ScriptLumpDocumentTab.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Data\ColorMap.cs" />
|
||||
<Compile Include="Data\DirectoryReader.cs" />
|
||||
<Compile Include="Data\FileImage.cs" />
|
||||
<Compile Include="Data\FlatImage.cs" />
|
||||
|
@ -1307,6 +1308,7 @@
|
|||
<None Include="Resources\Angle6.png" />
|
||||
<None Include="Resources\Angle7.png" />
|
||||
<None Include="Resources\AboutBack.png" />
|
||||
<Content Include="Resources\ClassicRendering.png" />
|
||||
<Content Include="Resources\DB2.ico" />
|
||||
<None Include="Resources\GZDB2.ico" />
|
||||
<None Include="Resources\UDB.ico" />
|
||||
|
@ -1365,6 +1367,7 @@
|
|||
<None Include="Resources\ScriptError.png" />
|
||||
<None Include="Resources\ScriptConstant.png" />
|
||||
<None Include="Resources\Sky.png" />
|
||||
<None Include="Resources\ClassicRendering.png" />
|
||||
<None Include="Resources\Update.png" />
|
||||
<None Include="Resources\Reload.png" />
|
||||
<None Include="Resources\Preferences.png" />
|
||||
|
|
|
@ -206,6 +206,7 @@
|
|||
<Compile Include="Controls\Scripting\ScriptLumpDocumentTab.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Data\ColorMap.cs" />
|
||||
<Compile Include="Data\DirectoryReader.cs" />
|
||||
<Compile Include="Data\FileImage.cs" />
|
||||
<Compile Include="Data\FlatImage.cs" />
|
||||
|
|
|
@ -146,6 +146,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private bool dynamicgridsize;
|
||||
private int ignoredremoterevision;
|
||||
|
||||
//volte
|
||||
private bool classicRendering;
|
||||
|
||||
// These are not stored in the configuration, only used at runtime
|
||||
private int defaultbrightness;
|
||||
private int defaultfloorheight;
|
||||
|
@ -270,6 +273,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public bool RenderGrid { get { return rendergrid; } internal set { rendergrid = value; } } //mxd
|
||||
public bool DynamicGridSize { get { return dynamicgridsize; } internal set { dynamicgridsize = value; } } //mxd
|
||||
internal int IgnoredRemoteRevision { get { return ignoredremoterevision; } set { ignoredremoterevision = value; } } //mxd
|
||||
|
||||
//volte
|
||||
public bool ClassicRendering { get { return classicRendering; } internal set { classicRendering = value; } }
|
||||
|
||||
//mxd. Left here for compatibility reasons...
|
||||
public string DefaultTexture { get { return General.Map != null ? General.Map.Options.DefaultWallTexture : "-"; } set { if(General.Map != null) General.Map.Options.DefaultWallTexture = value; } }
|
||||
|
@ -404,6 +410,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
dynamicgridsize = cfg.ReadSetting("dynamicgridsize", true); //mxd
|
||||
ignoredremoterevision = cfg.ReadSetting("ignoredremoterevision", 0); //mxd
|
||||
|
||||
// volte
|
||||
classicRendering = cfg.ReadSetting("classicrendering", false);
|
||||
|
||||
//mxd. Sector defaults
|
||||
defaultceilheight = cfg.ReadSetting("defaultceilheight", 128);
|
||||
defaultfloorheight = cfg.ReadSetting("defaultfloorheight", 0);
|
||||
|
@ -544,6 +553,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
cfg.WriteSetting("dynamicgridsize", dynamicgridsize); //mxd
|
||||
cfg.WriteSetting("ignoredremoterevision", ignoredremoterevision); //mxd
|
||||
|
||||
//volte
|
||||
cfg.WriteSetting("classicrendering", classicRendering);
|
||||
|
||||
//mxd. Sector defaults
|
||||
cfg.WriteSetting("defaultceilheight", defaultceilheight);
|
||||
cfg.WriteSetting("defaultfloorheight", defaultfloorheight);
|
||||
|
|
107
Source/Core/Data/ColorMap.cs
Normal file
107
Source/Core/Data/ColorMap.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
#region ================== Copyright
|
||||
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
public sealed class ColorMap
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private PixelColor[] colors;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public PixelColor this[int index] { get { return colors[index]; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public ColorMap()
|
||||
{
|
||||
colors = new PixelColor[34 * 256];
|
||||
for(int i = 0; i < 34 * 256; i++)
|
||||
{
|
||||
// Set colors to gray
|
||||
colors[i].r = 127;
|
||||
colors[i].g = 127;
|
||||
colors[i].b = 127;
|
||||
colors[i].a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public ColorMap(Stream stream, Playpal palette)
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
var colors = new List<PixelColor>();
|
||||
|
||||
// Read all palette entries
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
// Read colors
|
||||
var index = reader.ReadByte();
|
||||
var color = palette[index];
|
||||
colors.Add(color);
|
||||
}
|
||||
|
||||
this.colors = colors.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
public Bitmap CreateBitmap() {
|
||||
var width = 256;
|
||||
var height = (int)Math.Ceiling((float)colors.Length / 256);
|
||||
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int index = width * y + x;
|
||||
bitmap.SetPixel(x, y, colors[index].ToColor());
|
||||
}
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -66,7 +66,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// Palette
|
||||
private Playpal palette;
|
||||
|
||||
private ColorMap mainColormap;
|
||||
|
||||
// Textures, Flats and Sprites
|
||||
private Dictionary<long, ImageData> textures;
|
||||
private Dictionary<long, long> texturenamesshorttofull; //mxd
|
||||
|
@ -163,6 +164,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
internal IEnumerable<DataReader> Containers { get { return containers; } }
|
||||
|
||||
public Playpal Palette { get { return palette; } }
|
||||
public ColorMap MainColorMap { get { return mainColormap; } }
|
||||
public ICollection<ImageData> Textures { get { return textures.Values; } }
|
||||
public ICollection<ImageData> Flats { get { return flats.Values; } }
|
||||
public List<string> TextureNames { get { return texturenames; } }
|
||||
|
@ -428,6 +430,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Load stuff
|
||||
LoadX11R6RGB(); //mxd
|
||||
LoadPalette();
|
||||
LoadMainColorMap();
|
||||
Dictionary<string, TexturesParser> cachedparsers = new Dictionary<string, TexturesParser>(); //mxd
|
||||
int texcount = LoadTextures(texturesonly, texturenamesshorttofull, cachedparsers);
|
||||
int flatcount = LoadFlats(flatsonly, flatnamesshorttofull, cachedparsers);
|
||||
|
@ -839,6 +842,24 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
}
|
||||
|
||||
private void LoadMainColorMap()
|
||||
{
|
||||
// Go for all opened containers
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// Load palette
|
||||
mainColormap = containers[i].LoadMainColorMap(palette);
|
||||
if(mainColormap != null) break;
|
||||
}
|
||||
|
||||
// Make empty palette when still no palette found
|
||||
if(mainColormap == null)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "None of the loaded resources define a colormap. Did you forget to configure an IWAD for this game configuration?");
|
||||
mainColormap = new ColorMap();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
|
|
@ -21,6 +21,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
|
||||
#endregion
|
||||
|
@ -164,6 +165,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// When implemented, this should find and load a PLAYPAL palette
|
||||
public virtual Playpal LoadPalette() { return null; }
|
||||
|
||||
public virtual ColorMap LoadMainColorMap(Playpal palette) { return null; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public abstract unsafe class ImageData : IDisposable
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
||||
public const int TEXTURE_INDEXED = 1;
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -61,6 +62,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
protected bool hasPatchWithSameName; //mxd
|
||||
protected int namewidth; // biwa
|
||||
protected int shortnamewidth; // biwa
|
||||
protected bool wantIndexed; // volte
|
||||
|
||||
//mxd. Hashing
|
||||
private static int hashcounter;
|
||||
|
@ -85,6 +87,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private int mipmaplevels; // 0 = all mipmaps
|
||||
protected bool dynamictexture;
|
||||
private Texture texture;
|
||||
private Texture indexedTexture;
|
||||
|
||||
// Disposing
|
||||
protected bool isdisposed;
|
||||
|
@ -105,7 +108,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
|
||||
internal bool HasLongName { get { return hasLongName; } } //mxd
|
||||
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
|
||||
public Texture Texture { get { return GetTexture(); } }
|
||||
public Texture Texture { get { return GetTexture(false); } }
|
||||
public Texture IndexedTexture { get { return GetTexture(true); } }
|
||||
public bool IsPreviewLoaded
|
||||
{
|
||||
get
|
||||
|
@ -176,6 +180,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
previewbitmap?.Dispose();
|
||||
spritepreviewbitmap?.Dispose();
|
||||
texture?.Dispose();
|
||||
indexedTexture?.Dispose();
|
||||
loadedbitmap = null;
|
||||
previewbitmap = null;
|
||||
spritepreviewbitmap = null;
|
||||
|
@ -330,6 +335,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
loadedbitmap?.Dispose();
|
||||
texture?.Dispose();
|
||||
indexedTexture?.Dispose();
|
||||
imagestate = ImageLoadState.Ready;
|
||||
loadedbitmap = loadResult.bitmap;
|
||||
alphatest = loadResult.alphatest;
|
||||
|
@ -676,30 +682,78 @@ namespace CodeImp.DoomBuilder.Data
|
|||
loadResult.bitmap.UnlockBits(bmpdata);
|
||||
}
|
||||
|
||||
Texture GetTexture()
|
||||
Texture GetTexture(bool indexed = false)
|
||||
{
|
||||
if (texture != null)
|
||||
return texture;
|
||||
else if (imagestate == ImageLoadState.Loading)
|
||||
return General.Map.Data.LoadingTexture;
|
||||
else if (loadfailed)
|
||||
return General.Map.Data.FailedTexture;
|
||||
if (indexed && indexedTexture != null)
|
||||
return indexedTexture;
|
||||
if (!indexed && texture != null)
|
||||
return texture;
|
||||
|
||||
if (imagestate == ImageLoadState.None)
|
||||
{
|
||||
General.Map.Data.QueueLoadImage(this);
|
||||
return General.Map.Data.LoadingTexture;
|
||||
}
|
||||
if (indexed && !wantIndexed)
|
||||
{
|
||||
// indexed texture requested, but we didn't generate it, so we have to reload the image
|
||||
ReleaseTexture();
|
||||
imagestate = ImageLoadState.None;
|
||||
wantIndexed = true;
|
||||
}
|
||||
|
||||
if (imagestate == ImageLoadState.Loading)
|
||||
return General.Map.Data.LoadingTexture;
|
||||
if (loadfailed)
|
||||
return General.Map.Data.FailedTexture;
|
||||
|
||||
texture = new Texture(General.Map.Graphics, loadedbitmap);
|
||||
if (imagestate == ImageLoadState.None)
|
||||
{
|
||||
General.Map.Data.QueueLoadImage(this);
|
||||
return General.Map.Data.LoadingTexture;
|
||||
}
|
||||
|
||||
if (loadedbitmap == null)
|
||||
{
|
||||
return General.Map.Data.LoadingTexture;
|
||||
}
|
||||
|
||||
loadedbitmap.Dispose();
|
||||
loadedbitmap = null;
|
||||
texture = new Texture(General.Map.Graphics, loadedbitmap);
|
||||
if (wantIndexed)
|
||||
{
|
||||
Bitmap indexedBitmap = CreateIndexedBitmap(loadedbitmap, General.Map.Data.Palette);
|
||||
indexedTexture = new Texture(General.Map.Graphics, indexedBitmap);
|
||||
indexedTexture.UserData = TEXTURE_INDEXED;
|
||||
}
|
||||
|
||||
loadedbitmap.Dispose();
|
||||
loadedbitmap = null;
|
||||
|
||||
#if DEBUG
|
||||
texture.Tag = name; //mxd. Helps with tracking undisposed resources...
|
||||
#endif
|
||||
return texture;
|
||||
|
||||
return indexed ? indexedTexture : texture;
|
||||
}
|
||||
|
||||
Bitmap CreateIndexedBitmap(Bitmap original, Playpal palette)
|
||||
{
|
||||
int[] indices = new int[original.Width * original.Height];
|
||||
|
||||
Bitmap indexed = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
|
||||
BitmapData indata = original.LockBits(new Rectangle(0, 0, original.Size.Width, original.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
PixelColor* inpixels = (PixelColor*)indata.Scan0.ToPointer();
|
||||
General.Colors.QuantizeColorsToPlaypal(inpixels, indices, palette);
|
||||
|
||||
BitmapData outdata = indexed.LockBits(new Rectangle(0, 0, indexed.Size.Width, indexed.Size.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
PixelColor *outpixels = (PixelColor*)outdata.Scan0.ToPointer();
|
||||
for (int i = 0; i < indices.Length; i++)
|
||||
{
|
||||
outpixels[i].r = (byte)indices[i];
|
||||
outpixels[i].g = 0;
|
||||
outpixels[i].b = 0;
|
||||
outpixels[i].a = inpixels[i].a;
|
||||
}
|
||||
|
||||
original.UnlockBits(indata);
|
||||
indexed.UnlockBits(outdata);
|
||||
|
||||
return indexed;
|
||||
}
|
||||
|
||||
// This updates a dynamic texture
|
||||
|
@ -718,6 +772,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
texture?.Dispose();
|
||||
texture = null;
|
||||
indexedTexture?.Dispose();
|
||||
indexedTexture = null;
|
||||
}
|
||||
|
||||
// This returns a preview image
|
||||
|
|
|
@ -151,6 +151,37 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Done
|
||||
return palette;
|
||||
}
|
||||
|
||||
// This loads the COLORMAP
|
||||
public override ColorMap LoadMainColorMap(Playpal palette)
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Colormap from wad(s)
|
||||
ColorMap colormap = null;
|
||||
foreach(WADReader wr in wads)
|
||||
{
|
||||
ColorMap wadcolormap = wr.LoadMainColorMap(palette);
|
||||
if(wadcolormap != null) return wadcolormap;
|
||||
}
|
||||
|
||||
// Find in root directory
|
||||
string foundfile = FindFirstFile("COLORMAP", false);
|
||||
if((foundfile != null) && FileExists(foundfile))
|
||||
{
|
||||
MemoryStream stream = LoadFile(foundfile);
|
||||
|
||||
if(stream.Length >= 256) //mxd
|
||||
colormap = new ColorMap(stream, palette);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Warning: invalid colormap \"" + foundfile + "\"");
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
// Done
|
||||
return colormap;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
|
||||
|
@ -38,7 +41,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#region ================== Properties
|
||||
|
||||
public PixelColor this[int index] { get { return colors[index]; } }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
@ -84,6 +87,38 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
public Bitmap CreateBitmap() {
|
||||
var bitmap = new Bitmap(16, 16, PixelFormat.Format32bppRgb);
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int index = 16 * y + x;
|
||||
bitmap.SetPixel(x, y, colors[index].ToColor());
|
||||
}
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public int FindClosestColor(PixelColor match)
|
||||
{
|
||||
float minDist = 99999;
|
||||
int minIndex = 0;
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
PixelColor color = colors[i];
|
||||
float dr = (float)match.r - (float)color.r;
|
||||
float dg = (float)match.g - (float)color.g;
|
||||
float db = (float)match.b - (float)color.b;
|
||||
float sqDist = dr * dr + dg * dg + db * db;
|
||||
if (sqDist < minDist)
|
||||
{
|
||||
minIndex = i;
|
||||
minDist = sqDist;
|
||||
}
|
||||
}
|
||||
|
||||
return minIndex;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Config;
|
|||
using CodeImp.DoomBuilder.Data.Scripting;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
|
||||
#endregion
|
||||
|
@ -308,6 +309,21 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return null; // No palette
|
||||
}
|
||||
|
||||
public override ColorMap LoadMainColorMap(Playpal palette)
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Look for a lump named COLORMAP
|
||||
Lump lump = file.FindLump("COLORMAP");
|
||||
if (lump != null)
|
||||
{
|
||||
using (Stream s = lump.GetSafeStream())
|
||||
return new ColorMap(s, palette);
|
||||
}
|
||||
return null; // No palette
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
|
10
Source/Core/Properties/Resources.Designer.cs
generated
10
Source/Core/Properties/Resources.Designer.cs
generated
|
@ -210,6 +210,16 @@ namespace CodeImp.DoomBuilder.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap ClassicRendering {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("ClassicRendering", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -532,6 +532,9 @@
|
|||
<data name="Sky" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="ClassicRendering" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ClassicRendering.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Pin" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Pin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
||||
|
||||
#endregion
|
||||
|
@ -275,6 +276,12 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
cp->b = correctiontable[cp->b];
|
||||
}
|
||||
}
|
||||
|
||||
// This quantizes an image to a PLAYPAL lump, putting indices into an array of integers.
|
||||
internal unsafe void QuantizeColorsToPlaypal(PixelColor* inPixels, int[] indices, Playpal playpal)
|
||||
{
|
||||
System.Threading.Tasks.Parallel.For(0, indices.Length, (i) => indices[i] = playpal.FindClosestColor(inPixels[i]));
|
||||
}
|
||||
|
||||
// This clamps a value between 0 and 1
|
||||
private static float Saturate(float v)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System.Collections.Generic;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
@ -45,7 +46,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Rendering methods
|
||||
int CalculateBrightness(int level);
|
||||
int CalculateBrightness(int level, Sidedef sd); //mxd
|
||||
|
||||
|
||||
void SetClassicLightingColorMap(ColorMap colormap);
|
||||
void SetHighlightedObject(IVisualPickable obj);
|
||||
void AddSectorGeometry(VisualGeometry g);
|
||||
void AddThingGeometry(VisualThing t);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Controls;
|
||||
|
@ -69,6 +70,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
DeclareUniform(UniformName.sectorfogcolor, "sectorfogcolor", UniformType.Vec4f);
|
||||
DeclareUniform(UniformName.lightsEnabled, "lightsEnabled", UniformType.Float);
|
||||
DeclareUniform(UniformName.slopeHandleLength, "slopeHandleLength", UniformType.Float);
|
||||
|
||||
// volte: classic rendering
|
||||
DeclareUniform(UniformName.drawPaletted, "drawPaletted", UniformType.Int);
|
||||
DeclareUniform(UniformName.colormapSize, "colormapSize", UniformType.Vec2i);
|
||||
DeclareUniform(UniformName.lightLevel, "lightLevel", UniformType.Int);
|
||||
|
||||
// 2d fsaa
|
||||
CompileShader(ShaderName.display2d_fsaa, "display2d.shader", "display2d_fsaa");
|
||||
|
@ -90,6 +96,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
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");
|
||||
|
||||
// classic rendering
|
||||
CompileShader(ShaderName.world3d_classic, "world3d.shader", "world3d_classic");
|
||||
CompileShader(ShaderName.world3d_classic_highlight, "world3d.shader", "world3d_classic_highlight");
|
||||
|
||||
// skybox shader
|
||||
CompileShader(ShaderName.world3d_skybox, "world3d_skybox.shader", "world3d_skybox");
|
||||
|
@ -125,7 +135,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
Handle = RenderDevice_New(display, RenderTarget.Handle);
|
||||
if (Handle == IntPtr.Zero)
|
||||
throw new RenderDeviceException(string.Format("Could not create render device: {0}", BuilderNative_GetError()));
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(4096);
|
||||
BuilderNative_GetError(sb, sb.Capacity);
|
||||
throw new RenderDeviceException(string.Format("Could not create render device: {0}", sb));
|
||||
}
|
||||
}
|
||||
|
||||
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||
|
@ -133,7 +147,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
void ThrowIfFailed(bool result)
|
||||
{
|
||||
if (!result)
|
||||
throw new RenderDeviceException(BuilderNative_GetError());
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(4096);
|
||||
BuilderNative_GetError(sb, sb.Capacity);
|
||||
throw new RenderDeviceException(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -359,24 +377,24 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
RenderDevice_SetZWriteEnable(Handle, value);
|
||||
}
|
||||
|
||||
public void SetTexture(BaseTexture value)
|
||||
public void SetTexture(BaseTexture value, int unit = 0)
|
||||
{
|
||||
RenderDevice_SetTexture(Handle, value != null ? value.Handle : IntPtr.Zero);
|
||||
RenderDevice_SetTexture(Handle, unit, value != null ? value.Handle : IntPtr.Zero);
|
||||
}
|
||||
|
||||
public void SetSamplerFilter(TextureFilter filter)
|
||||
public void SetSamplerFilter(TextureFilter filter, int unit = 0)
|
||||
{
|
||||
SetSamplerFilter(filter, filter, MipmapFilter.None, 0.0f);
|
||||
SetSamplerFilter(filter, filter, MipmapFilter.None, 0.0f, unit);
|
||||
}
|
||||
|
||||
public void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy)
|
||||
public void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy, int unit = 0)
|
||||
{
|
||||
RenderDevice_SetSamplerFilter(Handle, minfilter, magfilter, mipfilter, maxanisotropy);
|
||||
RenderDevice_SetSamplerFilter(Handle, unit, minfilter, magfilter, mipfilter, maxanisotropy);
|
||||
}
|
||||
|
||||
public void SetSamplerState(TextureAddress address)
|
||||
public void SetSamplerState(TextureAddress address, int unit = 0)
|
||||
{
|
||||
RenderDevice_SetSamplerState(Handle, address);
|
||||
RenderDevice_SetSamplerState(Handle, unit, address);
|
||||
}
|
||||
|
||||
public void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount)
|
||||
|
@ -564,7 +582,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
static extern void RenderDevice_DeclareShader(IntPtr handle, ShaderName index, string name, string vertexShader, string fragShader);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
static extern string BuilderNative_GetError();
|
||||
static extern void BuilderNative_GetError(StringBuilder str, int length);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern bool RenderDevice_SetShader(IntPtr handle, ShaderName name);
|
||||
|
@ -615,13 +633,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
static extern void RenderDevice_SetZWriteEnable(IntPtr handle, bool value);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetTexture(IntPtr handle, IntPtr texture);
|
||||
static extern void RenderDevice_SetTexture(IntPtr handle, int unit, IntPtr texture);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetSamplerFilter(IntPtr handle, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy);
|
||||
static extern void RenderDevice_SetSamplerFilter(IntPtr handle, int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void RenderDevice_SetSamplerState(IntPtr handle, TextureAddress address);
|
||||
static extern void RenderDevice_SetSamplerState(IntPtr handle, int unit, TextureAddress address);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern bool RenderDevice_Draw(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount);
|
||||
|
@ -735,7 +753,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
world3d_main_highlight_fog_vertexcolor,
|
||||
world3d_vertex_color,
|
||||
world3d_constant_color,
|
||||
world3d_slope_handle
|
||||
world3d_slope_handle,
|
||||
world3d_classic,
|
||||
world3d_p19,
|
||||
world3d_classic_highlight
|
||||
}
|
||||
|
||||
public enum UniformType : int
|
||||
|
@ -778,7 +799,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
fogcolor,
|
||||
sectorfogcolor,
|
||||
lightsEnabled,
|
||||
slopeHandleLength
|
||||
slopeHandleLength,
|
||||
drawPaletted,
|
||||
colormapSize,
|
||||
lightLevel
|
||||
}
|
||||
|
||||
public enum VertexFormat : int { Flat, World }
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Disposing
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public static bool FullBrightness { get { return fullbrightness; } set { fullbrightness = value; } } //mxd
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
|
@ -26,6 +27,7 @@ using CodeImp.DoomBuilder.GZBuilder.MD3;
|
|||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.GZBuilder;
|
||||
using ColorMap = System.Drawing.Imaging.ColorMap;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -64,7 +66,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd
|
||||
private VisualVertexHandle vertexhandle;
|
||||
private int[] lightOffsets;
|
||||
|
||||
|
||||
private Data.ColorMap classicLightingColorMap = null;
|
||||
private Texture classicLightingColorMapTex = null;
|
||||
|
||||
// Slope handle
|
||||
private VisualSlopeHandle visualslopehandle;
|
||||
|
||||
|
@ -135,6 +140,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
public bool ShowSelection { get { return showselection; } set { showselection = value; } }
|
||||
public bool ShowHighlight { get { return showhighlight; } set { showhighlight = value; } }
|
||||
|
||||
protected bool UseIndexedTexture
|
||||
{
|
||||
get { return General.Settings.ClassicRendering && !fullbrightness; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
@ -294,6 +304,25 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
billboard = Matrix.RotationZ((float)(anglexy + Angle2D.PI));
|
||||
}
|
||||
|
||||
|
||||
// volte: Set the active colormap for classic lighting
|
||||
public void SetClassicLightingColorMap(Data.ColorMap colormap)
|
||||
{
|
||||
if (colormap == classicLightingColorMap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
classicLightingColorMap = colormap;
|
||||
if (classicLightingColorMap == null)
|
||||
{
|
||||
classicLightingColorMapTex = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
classicLightingColorMapTex = new Texture(graphics, classicLightingColorMap.CreateBitmap());
|
||||
}
|
||||
}
|
||||
|
||||
// This creates 2D view matrix
|
||||
private void CreateMatrices2D()
|
||||
{
|
||||
|
@ -302,7 +331,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
Matrix translate = Matrix.Translation(-(float)windowsize.Width * 0.5f, -(float)windowsize.Height * 0.5f, 0f);
|
||||
view2d = translate * scaling;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Start / Finish
|
||||
|
@ -327,13 +356,15 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
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
|
||||
TextureFilter texFilter = General.Settings.VisualBilinear ? TextureFilter.Linear : TextureFilter.Nearest;
|
||||
graphics.SetSamplerFilter(texFilter, texFilter, MipmapFilter.Linear, General.Settings.FilterAnisotropy);
|
||||
TextureFilter texFilter = (!General.Settings.ClassicRendering && General.Settings.VisualBilinear) ? TextureFilter.Linear : TextureFilter.Nearest;
|
||||
MipmapFilter mipFilter = General.Settings.ClassicRendering ? MipmapFilter.None : MipmapFilter.Linear;
|
||||
float aniso = General.Settings.ClassicRendering ? 0 : General.Settings.FilterAnisotropy;
|
||||
graphics.SetSamplerFilter(texFilter, texFilter, mipFilter, aniso);
|
||||
|
||||
// Texture addressing
|
||||
graphics.SetSamplerState(TextureAddress.Wrap);
|
||||
|
||||
// Matrices
|
||||
// Matrices
|
||||
world = Matrix.Identity;
|
||||
graphics.SetUniform(UniformName.projection, ref projection);
|
||||
graphics.SetUniform(UniformName.world, ref world);
|
||||
|
@ -352,7 +383,18 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
// Determine shader pass to use
|
||||
shaderpass = (fullbrightness ? ShaderName.world3d_fullbright : ShaderName.world3d_main);
|
||||
if (fullbrightness)
|
||||
{
|
||||
shaderpass = ShaderName.world3d_fullbright;
|
||||
}
|
||||
else if (General.Settings.ClassicRendering)
|
||||
{
|
||||
shaderpass = ShaderName.world3d_classic;
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderpass = ShaderName.world3d_main;
|
||||
}
|
||||
|
||||
// Create crosshair vertices
|
||||
if(crosshairverts == null)
|
||||
|
@ -787,14 +829,25 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
bool hadlights = false;
|
||||
|
||||
// volte: Set textures for classic lighting
|
||||
if (classicLightingColorMap != null)
|
||||
{
|
||||
graphics.SetUniform(UniformName.colormapSize, new Vector2i(classicLightingColorMapTex.Width, classicLightingColorMapTex.Height));
|
||||
graphics.SetTexture(classicLightingColorMapTex, 1);
|
||||
graphics.SetSamplerFilter(TextureFilter.Nearest, TextureFilter.Nearest, MipmapFilter.None, 0, 1);
|
||||
graphics.SetSamplerState(TextureAddress.Clamp, 1);
|
||||
}
|
||||
|
||||
// Render the geometry collected
|
||||
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
|
||||
{
|
||||
curtexture = group.Key;
|
||||
|
||||
// Apply texture
|
||||
graphics.SetTexture(curtexture.Texture);
|
||||
|
||||
// Apply texture
|
||||
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||
graphics.SetTexture(texture);
|
||||
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||
|
||||
//mxd. Sort geometry by sector index
|
||||
group.Value.Sort((g1, g2) => g1.Sector.Sector.FixedIndex - g2.Sector.Sector.FixedIndex);
|
||||
|
||||
|
@ -880,7 +933,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
ShaderName wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
//mxd. Render fog?
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && sector.Sector.FogMode != SectorFogMode.NONE)
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && !General.Settings.ClassicRendering && sector.Sector.FogMode != SectorFogMode.NONE)
|
||||
wantedshaderpass += 8;
|
||||
|
||||
// Switch shader pass?
|
||||
|
@ -895,6 +948,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.SetUniform(UniformName.modelnormal, Matrix.Identity);
|
||||
}
|
||||
}
|
||||
|
||||
// volte: set sector light level for classic rendering mode
|
||||
graphics.SetUniform(UniformName.lightLevel, sector.Sector.Brightness);
|
||||
|
||||
//mxd. Set variables for fog rendering?
|
||||
if(wantedshaderpass > ShaderName.world3d_p7)
|
||||
|
@ -933,8 +989,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
curtexture = group.Key;
|
||||
|
||||
// Apply texture
|
||||
graphics.SetTexture(curtexture.Texture);
|
||||
// Apply texture
|
||||
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||
graphics.SetTexture(texture);
|
||||
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||
|
||||
// Render all things with this texture
|
||||
foreach(VisualThing t in group.Value)
|
||||
|
@ -958,20 +1016,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
//mxd. If fog is enagled, switch to shader, which calculates it
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && !General.Settings.ClassicRendering && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
wantedshaderpass += 8;
|
||||
|
||||
//mxd. Create the matrix for positioning
|
||||
world = CreateThingPositionMatrix(t);
|
||||
|
||||
//mxd. If current thing is light - set it's color to light color
|
||||
if(t.LightType != null && t.LightType.LightInternal && !fullbrightness)
|
||||
if(t.LightType != null && t.LightType.LightInternal && !fullbrightness && !General.Settings.ClassicRendering)
|
||||
{
|
||||
wantedshaderpass += 4; // Render using one of passes, which uses World3D.VertexColor
|
||||
vertexcolor = t.LightColor;
|
||||
}
|
||||
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
|
||||
else if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && lightthings.Count > 0)
|
||||
else if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && !General.Settings.ClassicRendering && lightthings.Count > 0)
|
||||
{
|
||||
Color4 litcolor = GetLitColorForThing(t);
|
||||
if(litcolor.ToArgb() != 0)
|
||||
|
@ -1000,7 +1058,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
// Set the colors to use
|
||||
if(t.Thing.Sector != null) graphics.SetUniform(UniformName.sectorfogcolor, t.Thing.Sector.FogColor);
|
||||
if (t.Thing.Sector != null)
|
||||
{
|
||||
graphics.SetUniform(UniformName.lightLevel, t.Thing.Sector.Brightness);
|
||||
graphics.SetUniform(UniformName.sectorfogcolor, t.Thing.Sector.FogColor);
|
||||
}
|
||||
graphics.SetUniform(UniformName.vertexColor, vertexcolor);
|
||||
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)));
|
||||
|
||||
|
@ -1162,8 +1224,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
curtexture = g.Texture;
|
||||
|
||||
// Apply texture
|
||||
graphics.SetTexture(curtexture.Texture);
|
||||
// Apply texture
|
||||
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||
graphics.SetTexture(texture);
|
||||
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||
|
||||
curtexturename = g.Texture.LongName;
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1260,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
ShaderName wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
//mxd. Render fog?
|
||||
if (General.Settings.GZDrawFog && !fullbrightness && sector.Sector.FogMode != SectorFogMode.NONE)
|
||||
if (General.Settings.GZDrawFog && !fullbrightness && !General.Settings.ClassicRendering && sector.Sector.FogMode != SectorFogMode.NONE)
|
||||
wantedshaderpass += 8;
|
||||
|
||||
// Switch shader pass?
|
||||
|
@ -1294,8 +1359,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
curtexture = t.Texture;
|
||||
|
||||
// Apply texture
|
||||
graphics.SetTexture(curtexture.Texture);
|
||||
// Apply texture
|
||||
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||
graphics.SetTexture(texture);
|
||||
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||
|
||||
curtexturename = t.Texture.LongName;
|
||||
}
|
||||
|
||||
|
@ -1306,20 +1374,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
//mxd. if fog is enagled, switch to shader, which calculates it
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
if(General.Settings.GZDrawFog && !fullbrightness && !General.Settings.ClassicRendering && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
wantedshaderpass += 8;
|
||||
|
||||
//mxd. Create the matrix for positioning
|
||||
world = CreateThingPositionMatrix(t);
|
||||
|
||||
//mxd. If current thing is light - set it's color to light color
|
||||
if(t.LightType != null && t.LightType.LightInternal && !fullbrightness)
|
||||
if(t.LightType != null && t.LightType.LightInternal && !fullbrightness && !General.Settings.ClassicRendering)
|
||||
{
|
||||
wantedshaderpass += 4; // Render using one of passes, which uses World3D.VertexColor
|
||||
vertexcolor = t.LightColor;
|
||||
}
|
||||
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
|
||||
else if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && lightthings.Count > 0)
|
||||
else if(General.Settings.GZDrawLightsMode != LightRenderMode.NONE && !fullbrightness && !General.Settings.ClassicRendering && lightthings.Count > 0)
|
||||
{
|
||||
Color4 litcolor = GetLitColorForThing(t);
|
||||
if(litcolor.ToArgb() != 0)
|
||||
|
@ -1506,7 +1574,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
ShaderName wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
|
||||
|
||||
// If fog is enagled, switch to shader, which calculates it
|
||||
if (General.Settings.GZDrawFog && !fullbrightness && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
if (General.Settings.GZDrawFog && !fullbrightness && !General.Settings.ClassicRendering && t.Thing.Sector != null && t.Thing.Sector.FogMode != SectorFogMode.NONE)
|
||||
wantedshaderpass += 8;
|
||||
|
||||
// Switch shader pass?
|
||||
|
|
|
@ -1,111 +1,112 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public enum TextureFormat : int
|
||||
{
|
||||
Rgba8,
|
||||
Bgra8,
|
||||
Rg16f,
|
||||
Rgba16f,
|
||||
R32f,
|
||||
Rg32f,
|
||||
Rgb32f,
|
||||
Rgba32f,
|
||||
D32f_S8,
|
||||
D24_S8
|
||||
}
|
||||
|
||||
public class BaseTexture : IDisposable
|
||||
{
|
||||
public BaseTexture()
|
||||
{
|
||||
Handle = Texture_New();
|
||||
if (Handle == IntPtr.Zero)
|
||||
throw new Exception("Texture_New failed");
|
||||
}
|
||||
|
||||
~BaseTexture()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
Texture_Delete(Handle);
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
internal IntPtr Handle;
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern IntPtr Texture_New();
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_Delete(IntPtr handle);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height, TextureFormat format);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_SetCubeImage(IntPtr handle, int size, TextureFormat format);
|
||||
}
|
||||
|
||||
public class Texture : BaseTexture
|
||||
{
|
||||
public Texture(int width, int height, TextureFormat format)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Format = format;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
}
|
||||
|
||||
public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
|
||||
{
|
||||
Width = bitmap.Width;
|
||||
Height = bitmap.Height;
|
||||
Format = TextureFormat.Bgra8;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
device.SetPixels(this, bitmap);
|
||||
}
|
||||
|
||||
public Texture(RenderDevice device, System.Drawing.Image image)
|
||||
{
|
||||
using (var bitmap = new System.Drawing.Bitmap(image))
|
||||
{
|
||||
Width = bitmap.Width;
|
||||
Height = bitmap.Height;
|
||||
Format = TextureFormat.Bgra8;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
device.SetPixels(this, bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
public TextureFormat Format { get; private set; }
|
||||
|
||||
public object Tag { get; set; }
|
||||
}
|
||||
|
||||
public class CubeTexture : BaseTexture
|
||||
{
|
||||
public CubeTexture(RenderDevice device, int size)
|
||||
{
|
||||
Texture_SetCubeImage(Handle, size, TextureFormat.Bgra8);
|
||||
}
|
||||
}
|
||||
|
||||
public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ }
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public enum TextureFormat : int
|
||||
{
|
||||
Rgba8,
|
||||
Bgra8,
|
||||
Rg16f,
|
||||
Rgba16f,
|
||||
R32f,
|
||||
Rg32f,
|
||||
Rgb32f,
|
||||
Rgba32f,
|
||||
D32f_S8,
|
||||
D24_S8
|
||||
}
|
||||
|
||||
public class BaseTexture : IDisposable
|
||||
{
|
||||
public BaseTexture()
|
||||
{
|
||||
Handle = Texture_New();
|
||||
if (Handle == IntPtr.Zero)
|
||||
throw new Exception("Texture_New failed");
|
||||
}
|
||||
|
||||
~BaseTexture()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
Texture_Delete(Handle);
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
internal IntPtr Handle;
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern IntPtr Texture_New();
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_Delete(IntPtr handle);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height, TextureFormat format);
|
||||
|
||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||
protected static extern void Texture_SetCubeImage(IntPtr handle, int size, TextureFormat format);
|
||||
}
|
||||
|
||||
public class Texture : BaseTexture
|
||||
{
|
||||
public Texture(int width, int height, TextureFormat format)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Format = format;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
}
|
||||
|
||||
public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
|
||||
{
|
||||
Width = bitmap.Width;
|
||||
Height = bitmap.Height;
|
||||
Format = TextureFormat.Bgra8;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
device.SetPixels(this, bitmap);
|
||||
}
|
||||
|
||||
public Texture(RenderDevice device, System.Drawing.Image image)
|
||||
{
|
||||
using (var bitmap = new System.Drawing.Bitmap(image))
|
||||
{
|
||||
Width = bitmap.Width;
|
||||
Height = bitmap.Height;
|
||||
Format = TextureFormat.Bgra8;
|
||||
Texture_Set2DImage(Handle, Width, Height, Format);
|
||||
device.SetPixels(this, bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
public TextureFormat Format { get; private set; }
|
||||
|
||||
public object Tag { get; set; }
|
||||
public int UserData { get; set; }
|
||||
}
|
||||
|
||||
public class CubeTexture : BaseTexture
|
||||
{
|
||||
public CubeTexture(RenderDevice device, int size)
|
||||
{
|
||||
Texture_SetCubeImage(Handle, size, TextureFormat.Bgra8);
|
||||
}
|
||||
}
|
||||
|
||||
public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ }
|
||||
}
|
||||
|
|
|
@ -1330,6 +1330,16 @@ gztogglevisualvertices
|
|||
default = 262230;
|
||||
}
|
||||
|
||||
toggleclassicrendering
|
||||
{
|
||||
title = "Toggle classic rendering";
|
||||
category = "visual";
|
||||
description = "When enabled, attempts to simulate classic Doom rendering with banded light and palettized textures.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = false;
|
||||
}
|
||||
|
||||
gztoggleenhancedrendering
|
||||
{
|
||||
title = "Toggle Enhanced Rendering Effects";
|
||||
|
|
BIN
Source/Core/Resources/ClassicRendering.png
Normal file
BIN
Source/Core/Resources/ClassicRendering.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 KiB |
|
@ -6,7 +6,7 @@ uniforms
|
|||
mat4 modelnormal;
|
||||
vec4 campos;
|
||||
|
||||
vec4 highlightcolor;
|
||||
vec4 highlightcolor;
|
||||
vec4 stencilColor;
|
||||
float desaturation;
|
||||
|
||||
|
@ -16,30 +16,90 @@ uniforms
|
|||
vec4 vertexColor;
|
||||
|
||||
sampler2D texture1;
|
||||
sampler2D texture2;
|
||||
sampler2D texture3;
|
||||
|
||||
// classic lighting related
|
||||
int drawPaletted;
|
||||
ivec2 colormapSize;
|
||||
int lightLevel;
|
||||
|
||||
// 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;
|
||||
|
||||
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 getColorMappedColor(int entry, int depth)
|
||||
{
|
||||
vec2 uv = vec2((float(entry) + 0.5) / colormapSize.x, (float(depth) + 0.5) / colormapSize.y);
|
||||
vec4 colormapColor = texture(texture2, uv);
|
||||
return colormapColor;
|
||||
}
|
||||
|
||||
int classicLightLevelToColorMapOffset(int lightLevel, vec3 position, vec3 normal)
|
||||
{
|
||||
const int LIGHTLEVELS = 16;
|
||||
const int LIGHTSEGSHIFT = 4;
|
||||
const int NUMCOLORMAPS = 32;
|
||||
const int MAXLIGHTSCALE = 48;
|
||||
const int DISTMAP = 2;
|
||||
|
||||
int scaledLightLevel = lightLevel >> LIGHTSEGSHIFT;
|
||||
|
||||
bool isFlat = abs(dot(normal, vec3(0, 0, 1))) > 1e-3;
|
||||
|
||||
if (abs(dot(normal, vec3(0, 1, 0))) < 1e-3)
|
||||
{
|
||||
scaledLightLevel++;
|
||||
}
|
||||
else if (abs(dot(normal, vec3(1, 0, 0))) < 1e-3)
|
||||
{
|
||||
scaledLightLevel--;
|
||||
}
|
||||
|
||||
int level;
|
||||
float dist = distance(position, campos.xyz);
|
||||
|
||||
if (!isFlat)
|
||||
{
|
||||
int startmap = int(((LIGHTLEVELS-1-scaledLightLevel)*2)*NUMCOLORMAPS/LIGHTLEVELS);
|
||||
|
||||
// same calculation as Eternity Engine
|
||||
int index = int(2560.0 / dist);
|
||||
if (index >= MAXLIGHTSCALE) index = MAXLIGHTSCALE - 1;
|
||||
level = startmap - index / DISTMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
// same calculation as Eternity Engine
|
||||
float startmap = 2.0 * (30.0 - lightLevel / 8.0f);
|
||||
level = int(startmap - (1280.0f / dist)) + 1;
|
||||
}
|
||||
|
||||
|
||||
if (level < 0) level = 0;
|
||||
if (level >= NUMCOLORMAPS) level = NUMCOLORMAPS - 1;
|
||||
return level;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
@ -51,20 +111,20 @@ functions
|
|||
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;
|
||||
|
||||
//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;
|
||||
|
||||
|
@ -74,18 +134,18 @@ functions
|
|||
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;
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -136,11 +196,11 @@ shader world3d_main
|
|||
|
||||
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.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);
|
||||
}
|
||||
|
||||
|
@ -163,15 +223,15 @@ 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
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -180,25 +240,25 @@ shader world3d_main_highlight extends world3d_main
|
|||
{
|
||||
fragment
|
||||
{
|
||||
vec4 tcolor = texture(texture1, v2f.UV);
|
||||
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
||||
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 (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));
|
||||
}
|
||||
}
|
||||
|
@ -207,24 +267,24 @@ 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
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -233,12 +293,12 @@ shader world3d_vertex_color extends world3d_main
|
|||
{
|
||||
fragment
|
||||
{
|
||||
out.FragColor = v2f.Color;
|
||||
|
||||
#if defined(ALPHA_TEST)
|
||||
if (out.FragColor.a < 0.5) discard;
|
||||
#endif
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -247,9 +307,9 @@ 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.viewpos = view * world * vec4(in.Position, 1.0);
|
||||
gl_Position = projection * v2f.viewpos;
|
||||
v2f.Color = vertexColor;
|
||||
v2f.UV = in.TextureCoordinate;
|
||||
}
|
||||
}
|
||||
|
@ -258,12 +318,12 @@ shader world3d_constant_color extends world3d_main_vertexcolor
|
|||
{
|
||||
fragment
|
||||
{
|
||||
out.FragColor = vertexColor;
|
||||
|
||||
#if defined(ALPHA_TEST)
|
||||
if (out.FragColor.a < 0.5) discard;
|
||||
#endif
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -274,9 +334,9 @@ 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.viewpos = view * world * vec4(in.Position, 1.0);
|
||||
gl_Position = projection * v2f.viewpos;
|
||||
v2f.Color = vertexColor;
|
||||
v2f.UV = in.TextureCoordinate;
|
||||
}
|
||||
}
|
||||
|
@ -285,22 +345,22 @@ 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
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -309,25 +369,25 @@ 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 = vec4(getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal).rgb, tcolor.a);
|
||||
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
|
||||
|
||||
vec4 tcolor = texture(texture1, v2f.UV);
|
||||
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
||||
tcolor = vec4(getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal).rgb, tcolor.a);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -338,11 +398,11 @@ 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.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);
|
||||
}
|
||||
}
|
||||
|
@ -351,11 +411,11 @@ 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.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);
|
||||
}
|
||||
}
|
||||
|
@ -370,4 +430,67 @@ shader world3d_slope_handle extends world3d_vertex_color
|
|||
v2f.Color = in.Color * vertexColor;
|
||||
v2f.UV = in.TextureCoordinate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
shader world3d_classic extends world3d_main
|
||||
{
|
||||
fragment
|
||||
{
|
||||
vec4 pcolor;
|
||||
|
||||
if (bool(drawPaletted))
|
||||
{
|
||||
vec4 color = texture(texture1, v2f.UV);
|
||||
int entry = int(color.r * 255);
|
||||
float alpha = color.a;
|
||||
int colorMapOffset = classicLightLevelToColorMapOffset(lightLevel, v2f.PosW, v2f.Normal);
|
||||
pcolor = getColorMappedColor(entry, colorMapOffset);
|
||||
pcolor.a = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcolor = texture(texture1, v2f.UV);
|
||||
}
|
||||
|
||||
out.FragColor = pcolor;
|
||||
|
||||
#if defined(ALPHA_TEST)
|
||||
if (out.FragColor.a < 0.5) discard;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
shader world3d_classic_highlight extends world3d_main
|
||||
{
|
||||
fragment
|
||||
{
|
||||
vec4 pcolor;
|
||||
|
||||
if (bool(drawPaletted))
|
||||
{
|
||||
vec4 color = texture(texture1, v2f.UV);
|
||||
int entry = int(color.r * 255);
|
||||
float alpha = color.a;
|
||||
int modifiedLightLevel = max(lightLevel, 128);
|
||||
int colorMapOffset = classicLightLevelToColorMapOffset(modifiedLightLevel, v2f.PosW, v2f.Normal);
|
||||
pcolor = getColorMappedColor(entry, colorMapOffset);
|
||||
pcolor.a = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcolor = texture(texture1, v2f.UV);
|
||||
}
|
||||
|
||||
out.FragColor = pcolor;
|
||||
|
||||
if (pcolor.a > 0.0)
|
||||
{
|
||||
out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (pcolor.rgb - 0.4 * highlightcolor.a), max(pcolor.a + 0.25, 0.5));
|
||||
}
|
||||
|
||||
#if defined(ALPHA_TEST)
|
||||
if (out.FragColor.a < 0.5) discard;
|
||||
#endif
|
||||
}
|
||||
}
|
28
Source/Core/Windows/MainForm.Designer.cs
generated
28
Source/Core/Windows/MainForm.Designer.cs
generated
|
@ -191,6 +191,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.itemallmdl = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.itemtogglefog = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.itemtogglesky = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.itemtoggleclassicrendering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.itemtoggleeventlines = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.itemtogglevisualverts = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.buttonfullbrightness = new System.Windows.Forms.ToolStripButton();
|
||||
|
@ -224,6 +225,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.modelsshowall = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.buttontogglefog = new System.Windows.Forms.ToolStripButton();
|
||||
this.buttontogglesky = new System.Windows.Forms.ToolStripButton();
|
||||
this.buttontoggleclassicrendering = new System.Windows.Forms.ToolStripButton();
|
||||
this.buttontoggleeventlines = new System.Windows.Forms.ToolStripButton();
|
||||
this.buttontogglevisualvertices = new System.Windows.Forms.ToolStripButton();
|
||||
this.separatorgzmodes = new System.Windows.Forms.ToolStripSeparator();
|
||||
|
@ -798,6 +800,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.itemmodelmodes,
|
||||
this.itemtogglefog,
|
||||
this.itemtogglesky,
|
||||
this.itemtoggleclassicrendering,
|
||||
this.itemtoggleeventlines,
|
||||
this.itemtogglevisualverts,
|
||||
this.separatorhelpers,
|
||||
|
@ -1395,6 +1398,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.modelrendermode,
|
||||
this.buttontogglefog,
|
||||
this.buttontogglesky,
|
||||
this.buttontoggleclassicrendering,
|
||||
this.buttontoggleeventlines,
|
||||
this.buttontogglevisualvertices,
|
||||
this.separatorgzmodes,
|
||||
|
@ -1797,6 +1801,16 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.itemtogglesky.Text = "Render sky (Visual mode)";
|
||||
this.itemtogglesky.Click += new System.EventHandler(this.InvokeTaggedAction);
|
||||
//
|
||||
// itemclassicrendering
|
||||
//
|
||||
this.itemtoggleclassicrendering.CheckOnClick = true;
|
||||
this.itemtoggleclassicrendering.Image = global::CodeImp.DoomBuilder.Properties.Resources.ClassicRendering;
|
||||
this.itemtoggleclassicrendering.Name = "itemtoggleclassicrendering";
|
||||
this.itemtoggleclassicrendering.Size = new System.Drawing.Size(273, 22);
|
||||
this.itemtoggleclassicrendering.Tag = "builder_toggleclassicrendering";
|
||||
this.itemtoggleclassicrendering.Text = "Classic rendering (Visual mode)";
|
||||
this.itemtoggleclassicrendering.Click += new System.EventHandler(this.InvokeTaggedAction);
|
||||
//
|
||||
// itemeventlines
|
||||
//
|
||||
this.itemtoggleeventlines.CheckOnClick = true;
|
||||
|
@ -2170,6 +2184,18 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.buttontogglesky.Text = "Render Sky (Visual mode)";
|
||||
this.buttontogglesky.Click += new System.EventHandler(this.InvokeTaggedAction);
|
||||
//
|
||||
// buttontoggleclassicrendering
|
||||
//
|
||||
this.buttontoggleclassicrendering.CheckOnClick = true;
|
||||
this.buttontoggleclassicrendering.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.buttontoggleclassicrendering.Image = global::CodeImp.DoomBuilder.Properties.Resources.ClassicRendering;
|
||||
this.buttontoggleclassicrendering.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.buttontoggleclassicrendering.Name = "buttontoggleclassicrendering";
|
||||
this.buttontoggleclassicrendering.Size = new System.Drawing.Size(23, 20);
|
||||
this.buttontoggleclassicrendering.Tag = "builder_toggleclassicrendering";
|
||||
this.buttontoggleclassicrendering.Text = "Classic Rendering (Visual mode)";
|
||||
this.buttontoggleclassicrendering.Click += new System.EventHandler(this.InvokeTaggedAction);
|
||||
//
|
||||
// buttontoggleeventlines
|
||||
//
|
||||
this.buttontoggleeventlines.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
|
@ -3013,6 +3039,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
private System.Windows.Forms.ToolStripSeparator seperatorgeometry;
|
||||
private System.Windows.Forms.ToolStripButton buttontogglefog;
|
||||
private System.Windows.Forms.ToolStripButton buttontogglesky;
|
||||
private System.Windows.Forms.ToolStripButton buttontoggleclassicrendering;
|
||||
private System.Windows.Forms.ToolStripStatusLabel warnsLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemReloadModedef;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemReloadGldefs;
|
||||
|
@ -3072,6 +3099,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
private System.Windows.Forms.ToolStripMenuItem itemallmdl;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemtogglefog;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemtogglesky;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemtoggleclassicrendering;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemtoggleeventlines;
|
||||
private System.Windows.Forms.ToolStripMenuItem itemtogglevisualverts;
|
||||
private ToolStripMenuItem itemimport;
|
||||
|
|
|
@ -2164,6 +2164,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
buttonsplitjoinedsectors.Checked = General.Settings.SplitJoinedSectors; //mxd
|
||||
buttonautoclearsidetextures.Visible = General.Settings.ToolbarGeometry && maploaded; //mxd
|
||||
buttontest.Visible = General.Settings.ToolbarTesting && maploaded;
|
||||
buttontoggleclassicrendering.Visible = General.Settings.ToolbarViewModes && maploaded;
|
||||
|
||||
//mxd
|
||||
modelrendermode.Visible = General.Settings.GZToolbarGZDoom && maploaded;
|
||||
|
@ -2330,6 +2331,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
|
||||
buttontogglefog.Checked = General.Settings.GZDrawFog;
|
||||
buttontogglesky.Checked = General.Settings.GZDrawSky;
|
||||
buttontoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||
buttontoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
||||
buttontogglevisualvertices.Visible = General.Map.UDMF;
|
||||
buttontogglevisualvertices.Checked = General.Settings.GZShowVisualVertices;
|
||||
|
@ -3141,6 +3143,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
itemtogglefixedthingsscale.Checked = General.Settings.FixedThingsScale; //mxd
|
||||
itemtogglefog.Checked = General.Settings.GZDrawFog;
|
||||
itemtogglesky.Checked = General.Settings.GZDrawSky;
|
||||
itemtoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||
itemtoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
||||
itemtogglevisualverts.Visible = (General.Map != null && General.Map.UDMF);
|
||||
itemtogglevisualverts.Checked = General.Settings.GZShowVisualVertices;
|
||||
|
@ -3214,6 +3217,20 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
General.MainWindow.RedrawDisplay();
|
||||
General.MainWindow.UpdateGZDoomPanel();
|
||||
}
|
||||
|
||||
//mxd
|
||||
[BeginAction("toggleclassicrendering")]
|
||||
internal void ToggleClassicRendering()
|
||||
{
|
||||
General.Settings.ClassicRendering = !General.Settings.ClassicRendering;
|
||||
|
||||
itemtoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||
buttontoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||
|
||||
General.MainWindow.DisplayStatus(StatusType.Action, "Classic rendering is " + (General.Settings.ClassicRendering ? "ENABLED" : "DISABLED"));
|
||||
General.MainWindow.RedrawDisplay();
|
||||
General.MainWindow.UpdateGZDoomPanel();
|
||||
}
|
||||
|
||||
[BeginAction("gztoggleeventlines")]
|
||||
internal void ToggleEventLines()
|
||||
|
|
|
@ -76,9 +76,12 @@ extern "C"
|
|||
Backend::Get()->DeleteRenderDevice(device);
|
||||
}
|
||||
|
||||
const char* BuilderNative_GetError()
|
||||
void BuilderNative_GetError(char *out, int len)
|
||||
{
|
||||
return GetError();
|
||||
std::string result = mLastError;
|
||||
result = result.substr(0, len);
|
||||
std::copy(result.begin(), result.end(), out);
|
||||
out[std::min(len - 1, (int)result.size())] = 0;
|
||||
}
|
||||
|
||||
void RenderDevice_DeclareUniform(RenderDevice* device, UniformName name, const char* variablename, UniformType type)
|
||||
|
@ -161,19 +164,19 @@ extern "C"
|
|||
device->SetZWriteEnable(value);
|
||||
}
|
||||
|
||||
void RenderDevice_SetTexture(RenderDevice* device, Texture* texture)
|
||||
void RenderDevice_SetTexture(RenderDevice* device, int unit, Texture* texture)
|
||||
{
|
||||
device->SetTexture(texture);
|
||||
device->SetTexture(unit, texture);
|
||||
}
|
||||
|
||||
void RenderDevice_SetSamplerFilter(RenderDevice* device, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy)
|
||||
void RenderDevice_SetSamplerFilter(RenderDevice* device, int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy)
|
||||
{
|
||||
device->SetSamplerFilter(minfilter, magfilter, mipfilter, maxanisotropy);
|
||||
device->SetSamplerFilter(unit, minfilter, magfilter, mipfilter, maxanisotropy);
|
||||
}
|
||||
|
||||
void RenderDevice_SetSamplerState(RenderDevice* device, TextureAddress address)
|
||||
void RenderDevice_SetSamplerState(RenderDevice* device, int unit, TextureAddress address)
|
||||
{
|
||||
device->SetSamplerState(address);
|
||||
device->SetSamplerState(unit, address);
|
||||
}
|
||||
|
||||
bool RenderDevice_Draw(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount)
|
||||
|
|
|
@ -83,9 +83,9 @@ public:
|
|||
virtual void SetMultisampleAntialias(bool value) = 0;
|
||||
virtual void SetZEnable(bool value) = 0;
|
||||
virtual void SetZWriteEnable(bool value) = 0;
|
||||
virtual void SetTexture(Texture* texture) = 0;
|
||||
virtual void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) = 0;
|
||||
virtual void SetSamplerState(TextureAddress address) = 0;
|
||||
virtual void SetTexture(int unit, Texture* texture) = 0;
|
||||
virtual void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) = 0;
|
||||
virtual void SetSamplerState(int unit, TextureAddress address) = 0;
|
||||
virtual bool Draw(PrimitiveType type, int startIndex, int primitiveCount) = 0;
|
||||
virtual bool DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) = 0;
|
||||
virtual bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) = 0;
|
||||
|
|
|
@ -113,16 +113,15 @@ GLRenderDevice::~GLRenderDevice()
|
|||
glDeleteVertexArrays(1, &handle);
|
||||
}
|
||||
|
||||
for (auto& it : mSamplers)
|
||||
for (auto& it : mTextureUnit)
|
||||
{
|
||||
for (GLuint handle : it.second.WrapModes)
|
||||
{
|
||||
if (handle != 0)
|
||||
glDeleteSamplers(1, &handle);
|
||||
}
|
||||
GLuint &handle = it.SamplerHandle;
|
||||
if (handle != 0)
|
||||
{
|
||||
glDeleteSamplers(1, &handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mShaderManager->ReleaseResources();
|
||||
Context->ClearCurrent();
|
||||
}
|
||||
|
@ -264,30 +263,49 @@ void GLRenderDevice::SetZWriteEnable(bool value)
|
|||
}
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetTexture(Texture* texture)
|
||||
void GLRenderDevice::SetTexture(int unit, Texture* texture)
|
||||
{
|
||||
if (mTextureUnit.Tex != texture)
|
||||
if (mTextureUnit[unit].Tex != texture)
|
||||
{
|
||||
mTextureUnit.Tex = static_cast<GLTexture*>(texture);
|
||||
mTextureUnit[unit].Tex = static_cast<GLTexture*>(texture);
|
||||
mNeedApply = true;
|
||||
mTexturesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy)
|
||||
void GLRenderDevice::SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy)
|
||||
{
|
||||
SamplerFilterKey key;
|
||||
key.MinFilter = GetGLMinFilter(minfilter, mipfilter);
|
||||
key.MagFilter = (magfilter == TextureFilter::Nearest) ? GL_NEAREST : GL_LINEAR;
|
||||
key.MaxAnisotropy = maxanisotropy;
|
||||
if (mSamplerFilterKey != key)
|
||||
{
|
||||
mSamplerFilterKey = key;
|
||||
mSamplerFilter = &mSamplers[mSamplerFilterKey];
|
||||
bool dirty = false;
|
||||
|
||||
if (mTextureUnit[unit].MinFilter != minfilter)
|
||||
{
|
||||
mTextureUnit[unit].MinFilter = minfilter;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (mTextureUnit[unit].MagFilter != magfilter)
|
||||
{
|
||||
mTextureUnit[unit].MagFilter = magfilter;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (mTextureUnit[unit].MipFilter != mipfilter)
|
||||
{
|
||||
mTextureUnit[unit].MipFilter = mipfilter;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
mNeedApply = true;
|
||||
mTexturesChanged = true;
|
||||
}
|
||||
if ( mTextureUnit[unit].MaxAnisotropy != maxanisotropy)
|
||||
{
|
||||
mTextureUnit[unit].MaxAnisotropy = maxanisotropy;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
mNeedApply = true;
|
||||
mTexturesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
GLint GLRenderDevice::GetGLMinFilter(TextureFilter filter, MipmapFilter mipfilter)
|
||||
|
@ -315,11 +333,20 @@ GLint GLRenderDevice::GetGLMinFilter(TextureFilter filter, MipmapFilter mipfilte
|
|||
}
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetSamplerState(TextureAddress address)
|
||||
GLRenderDevice::SamplerFilterKey GLRenderDevice::GetSamplerFilterKey(TextureFilter filter, MipmapFilter mipFilter, float maxAnisotropy)
|
||||
{
|
||||
if (mTextureUnit.WrapMode != address)
|
||||
SamplerFilterKey key;
|
||||
key.MinFilter = GetGLMinFilter(filter, mipFilter);
|
||||
key.MagFilter = (filter == TextureFilter::Linear) ? GL_LINEAR : GL_NEAREST;
|
||||
key.MaxAnisotropy = maxAnisotropy;
|
||||
return key;
|
||||
}
|
||||
|
||||
void GLRenderDevice::SetSamplerState(int unit, TextureAddress address)
|
||||
{
|
||||
if (mTextureUnit[unit].WrapMode != address)
|
||||
{
|
||||
mTextureUnit.WrapMode = address;
|
||||
mTextureUnit[unit].WrapMode = address;
|
||||
mNeedApply = true;
|
||||
mTexturesChanged = true;
|
||||
}
|
||||
|
@ -901,42 +928,47 @@ bool GLRenderDevice::ApplyUniforms()
|
|||
|
||||
bool GLRenderDevice::ApplyTextures()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (mTextureUnit.Tex)
|
||||
{
|
||||
GLenum target = mTextureUnit.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||
bool hasError = false;
|
||||
for (int index = 0; index < 10; index++)
|
||||
{
|
||||
TextureUnit &unit = mTextureUnit[index];
|
||||
if (unit.Tex)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
GLenum target = unit.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||
|
||||
glBindTexture(target, unit.Tex->GetTexture(this));
|
||||
|
||||
glBindTexture(target, mTextureUnit.Tex->GetTexture(this));
|
||||
SamplerFilterKey key = GetSamplerFilterKey(unit.MagFilter, unit.MipFilter, unit.MaxAnisotropy);
|
||||
SamplerFilter &filter = mSamplers[key];
|
||||
GLuint &samplerHandle = filter.WrapModes[(int)unit.WrapMode];
|
||||
|
||||
GLuint& samplerHandle = mSamplerFilter->WrapModes[(int)mTextureUnit.WrapMode];
|
||||
if (samplerHandle == 0)
|
||||
{
|
||||
static const int wrapMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE };
|
||||
if (samplerHandle == 0)
|
||||
{
|
||||
static const int wrapMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE };
|
||||
|
||||
glGenSamplers(1, &samplerHandle);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, mSamplerFilterKey.MinFilter);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, mSamplerFilterKey.MagFilter);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrapMode[(int)mTextureUnit.WrapMode]);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrapMode[(int)mTextureUnit.WrapMode]);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrapMode[(int)mTextureUnit.WrapMode]);
|
||||
if (mSamplerFilterKey.MaxAnisotropy > 0.0f)
|
||||
glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, mSamplerFilterKey.MaxAnisotropy);
|
||||
}
|
||||
|
||||
if (mTextureUnit.SamplerHandle != samplerHandle)
|
||||
{
|
||||
mTextureUnit.SamplerHandle = samplerHandle;
|
||||
glBindSampler(0, samplerHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
mTexturesChanged = false;
|
||||
|
||||
return CheckGLError();
|
||||
glGenSamplers(1, &samplerHandle);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, key.MinFilter);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, key.MagFilter);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrapMode[(int)unit.WrapMode]);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrapMode[(int)unit.WrapMode]);
|
||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrapMode[(int)unit.WrapMode]);
|
||||
if (key.MaxAnisotropy > 0.0f)
|
||||
glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, key.MaxAnisotropy);
|
||||
}
|
||||
|
||||
if (unit.SamplerHandle != samplerHandle)
|
||||
{
|
||||
unit.SamplerHandle = samplerHandle;
|
||||
glBindSampler(index, samplerHandle);
|
||||
}
|
||||
}
|
||||
|
||||
hasError |= CheckGLError();
|
||||
}
|
||||
|
||||
mTexturesChanged = false;
|
||||
return hasError;
|
||||
}
|
||||
|
||||
std::mutex& GLRenderDevice::GetMutex()
|
||||
|
|
|
@ -54,9 +54,9 @@ public:
|
|||
void SetMultisampleAntialias(bool value) override;
|
||||
void SetZEnable(bool value) override;
|
||||
void SetZWriteEnable(bool value) override;
|
||||
void SetTexture(Texture* texture) override;
|
||||
void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) override;
|
||||
void SetSamplerState(TextureAddress address) override;
|
||||
void SetTexture(int unit, Texture* texture) override;
|
||||
void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) override;
|
||||
void SetSamplerState(int unit, TextureAddress address) override;
|
||||
bool Draw(PrimitiveType type, int startIndex, int primitiveCount) override;
|
||||
bool DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) override;
|
||||
bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) override;
|
||||
|
@ -114,13 +114,17 @@ public:
|
|||
std::vector<GLIndexBuffer*> IndexBuffers;
|
||||
std::vector<GLTexture*> Textures;
|
||||
} mDeleteList;
|
||||
|
||||
|
||||
struct TextureUnit
|
||||
{
|
||||
GLTexture* Tex = nullptr;
|
||||
TextureAddress WrapMode = TextureAddress::Wrap;
|
||||
GLuint SamplerHandle = 0;
|
||||
} mTextureUnit;
|
||||
TextureFilter MinFilter = TextureFilter::Nearest;
|
||||
TextureFilter MagFilter = TextureFilter::Nearest;
|
||||
MipmapFilter MipFilter = MipmapFilter::None;
|
||||
float MaxAnisotropy = 1;
|
||||
} mTextureUnit[10];
|
||||
|
||||
struct SamplerFilterKey
|
||||
{
|
||||
|
@ -132,15 +136,15 @@ public:
|
|||
bool operator==(const SamplerFilterKey& b) const { return memcmp(this, &b, sizeof(SamplerFilterKey)) == 0; }
|
||||
bool operator!=(const SamplerFilterKey& b) const { return memcmp(this, &b, sizeof(SamplerFilterKey)) != 0; }
|
||||
};
|
||||
|
||||
|
||||
struct SamplerFilter
|
||||
{
|
||||
GLuint WrapModes[2] = { 0, 0 };
|
||||
};
|
||||
{
|
||||
GLuint WrapModes[2] = { 0, 0 };
|
||||
};
|
||||
|
||||
std::map<SamplerFilterKey, SamplerFilter> mSamplers;
|
||||
SamplerFilterKey mSamplerFilterKey;
|
||||
SamplerFilter* mSamplerFilter = nullptr;
|
||||
std::map<SamplerFilterKey, SamplerFilter> mSamplers;
|
||||
|
||||
SamplerFilterKey GetSamplerFilterKey(TextureFilter filter, MipmapFilter mipFilter, float maxAnisotropy);
|
||||
|
||||
int mVertexBuffer = -1;
|
||||
int64_t mVertexBufferStartIndex = 0;
|
||||
|
|
|
@ -41,6 +41,8 @@ bool GLShader::CheckCompile(GLRenderDevice* device)
|
|||
CreateProgram(device);
|
||||
glUseProgram(mProgram);
|
||||
glUniform1i(glGetUniformLocation(mProgram, "texture1"), 0);
|
||||
glUniform1i(glGetUniformLocation(mProgram, "texture2"), 1);
|
||||
glUniform1i(glGetUniformLocation(mProgram, "texture3"), 2);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ bool GLTexture::SetPixels(GLRenderDevice* device, const void* data)
|
|||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, mTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), data);
|
||||
if (data != nullptr)
|
||||
if (data != nullptr)
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
//
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
|
|
|
@ -1614,6 +1614,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This draws a frame
|
||||
public override void OnRedrawDisplay()
|
||||
{
|
||||
renderer.SetClassicLightingColorMap(General.Map.Data.MainColorMap);
|
||||
|
||||
// Start drawing
|
||||
if(renderer.Start())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue