mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-25 13:21:28 +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/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/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/=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">
|
<Compile Include="Controls\Scripting\ScriptLumpDocumentTab.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Data\ColorMap.cs" />
|
||||||
<Compile Include="Data\DirectoryReader.cs" />
|
<Compile Include="Data\DirectoryReader.cs" />
|
||||||
<Compile Include="Data\FileImage.cs" />
|
<Compile Include="Data\FileImage.cs" />
|
||||||
<Compile Include="Data\FlatImage.cs" />
|
<Compile Include="Data\FlatImage.cs" />
|
||||||
|
@ -1307,6 +1308,7 @@
|
||||||
<None Include="Resources\Angle6.png" />
|
<None Include="Resources\Angle6.png" />
|
||||||
<None Include="Resources\Angle7.png" />
|
<None Include="Resources\Angle7.png" />
|
||||||
<None Include="Resources\AboutBack.png" />
|
<None Include="Resources\AboutBack.png" />
|
||||||
|
<Content Include="Resources\ClassicRendering.png" />
|
||||||
<Content Include="Resources\DB2.ico" />
|
<Content Include="Resources\DB2.ico" />
|
||||||
<None Include="Resources\GZDB2.ico" />
|
<None Include="Resources\GZDB2.ico" />
|
||||||
<None Include="Resources\UDB.ico" />
|
<None Include="Resources\UDB.ico" />
|
||||||
|
@ -1365,6 +1367,7 @@
|
||||||
<None Include="Resources\ScriptError.png" />
|
<None Include="Resources\ScriptError.png" />
|
||||||
<None Include="Resources\ScriptConstant.png" />
|
<None Include="Resources\ScriptConstant.png" />
|
||||||
<None Include="Resources\Sky.png" />
|
<None Include="Resources\Sky.png" />
|
||||||
|
<None Include="Resources\ClassicRendering.png" />
|
||||||
<None Include="Resources\Update.png" />
|
<None Include="Resources\Update.png" />
|
||||||
<None Include="Resources\Reload.png" />
|
<None Include="Resources\Reload.png" />
|
||||||
<None Include="Resources\Preferences.png" />
|
<None Include="Resources\Preferences.png" />
|
||||||
|
|
|
@ -206,6 +206,7 @@
|
||||||
<Compile Include="Controls\Scripting\ScriptLumpDocumentTab.cs">
|
<Compile Include="Controls\Scripting\ScriptLumpDocumentTab.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Data\ColorMap.cs" />
|
||||||
<Compile Include="Data\DirectoryReader.cs" />
|
<Compile Include="Data\DirectoryReader.cs" />
|
||||||
<Compile Include="Data\FileImage.cs" />
|
<Compile Include="Data\FileImage.cs" />
|
||||||
<Compile Include="Data\FlatImage.cs" />
|
<Compile Include="Data\FlatImage.cs" />
|
||||||
|
|
|
@ -146,6 +146,9 @@ namespace CodeImp.DoomBuilder.Config
|
||||||
private bool dynamicgridsize;
|
private bool dynamicgridsize;
|
||||||
private int ignoredremoterevision;
|
private int ignoredremoterevision;
|
||||||
|
|
||||||
|
//volte
|
||||||
|
private bool classicRendering;
|
||||||
|
|
||||||
// These are not stored in the configuration, only used at runtime
|
// These are not stored in the configuration, only used at runtime
|
||||||
private int defaultbrightness;
|
private int defaultbrightness;
|
||||||
private int defaultfloorheight;
|
private int defaultfloorheight;
|
||||||
|
@ -271,6 +274,9 @@ namespace CodeImp.DoomBuilder.Config
|
||||||
public bool DynamicGridSize { get { return dynamicgridsize; } internal set { dynamicgridsize = value; } } //mxd
|
public bool DynamicGridSize { get { return dynamicgridsize; } internal set { dynamicgridsize = value; } } //mxd
|
||||||
internal int IgnoredRemoteRevision { get { return ignoredremoterevision; } set { ignoredremoterevision = 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...
|
//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; } }
|
public string DefaultTexture { get { return General.Map != null ? General.Map.Options.DefaultWallTexture : "-"; } set { if(General.Map != null) General.Map.Options.DefaultWallTexture = value; } }
|
||||||
public string DefaultFloorTexture { get { return General.Map != null ? General.Map.Options.DefaultFloorTexture : "-"; } set { if(General.Map != null) General.Map.Options.DefaultFloorTexture = value; } }
|
public string DefaultFloorTexture { get { return General.Map != null ? General.Map.Options.DefaultFloorTexture : "-"; } set { if(General.Map != null) General.Map.Options.DefaultFloorTexture = value; } }
|
||||||
|
@ -404,6 +410,9 @@ namespace CodeImp.DoomBuilder.Config
|
||||||
dynamicgridsize = cfg.ReadSetting("dynamicgridsize", true); //mxd
|
dynamicgridsize = cfg.ReadSetting("dynamicgridsize", true); //mxd
|
||||||
ignoredremoterevision = cfg.ReadSetting("ignoredremoterevision", 0); //mxd
|
ignoredremoterevision = cfg.ReadSetting("ignoredremoterevision", 0); //mxd
|
||||||
|
|
||||||
|
// volte
|
||||||
|
classicRendering = cfg.ReadSetting("classicrendering", false);
|
||||||
|
|
||||||
//mxd. Sector defaults
|
//mxd. Sector defaults
|
||||||
defaultceilheight = cfg.ReadSetting("defaultceilheight", 128);
|
defaultceilheight = cfg.ReadSetting("defaultceilheight", 128);
|
||||||
defaultfloorheight = cfg.ReadSetting("defaultfloorheight", 0);
|
defaultfloorheight = cfg.ReadSetting("defaultfloorheight", 0);
|
||||||
|
@ -544,6 +553,9 @@ namespace CodeImp.DoomBuilder.Config
|
||||||
cfg.WriteSetting("dynamicgridsize", dynamicgridsize); //mxd
|
cfg.WriteSetting("dynamicgridsize", dynamicgridsize); //mxd
|
||||||
cfg.WriteSetting("ignoredremoterevision", ignoredremoterevision); //mxd
|
cfg.WriteSetting("ignoredremoterevision", ignoredremoterevision); //mxd
|
||||||
|
|
||||||
|
//volte
|
||||||
|
cfg.WriteSetting("classicrendering", classicRendering);
|
||||||
|
|
||||||
//mxd. Sector defaults
|
//mxd. Sector defaults
|
||||||
cfg.WriteSetting("defaultceilheight", defaultceilheight);
|
cfg.WriteSetting("defaultceilheight", defaultceilheight);
|
||||||
cfg.WriteSetting("defaultfloorheight", defaultfloorheight);
|
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,6 +66,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
|
|
||||||
// Palette
|
// Palette
|
||||||
private Playpal palette;
|
private Playpal palette;
|
||||||
|
private ColorMap mainColormap;
|
||||||
|
|
||||||
// Textures, Flats and Sprites
|
// Textures, Flats and Sprites
|
||||||
private Dictionary<long, ImageData> textures;
|
private Dictionary<long, ImageData> textures;
|
||||||
|
@ -163,6 +164,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
internal IEnumerable<DataReader> Containers { get { return containers; } }
|
internal IEnumerable<DataReader> Containers { get { return containers; } }
|
||||||
|
|
||||||
public Playpal Palette { get { return palette; } }
|
public Playpal Palette { get { return palette; } }
|
||||||
|
public ColorMap MainColorMap { get { return mainColormap; } }
|
||||||
public ICollection<ImageData> Textures { get { return textures.Values; } }
|
public ICollection<ImageData> Textures { get { return textures.Values; } }
|
||||||
public ICollection<ImageData> Flats { get { return flats.Values; } }
|
public ICollection<ImageData> Flats { get { return flats.Values; } }
|
||||||
public List<string> TextureNames { get { return texturenames; } }
|
public List<string> TextureNames { get { return texturenames; } }
|
||||||
|
@ -428,6 +430,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
// Load stuff
|
// Load stuff
|
||||||
LoadX11R6RGB(); //mxd
|
LoadX11R6RGB(); //mxd
|
||||||
LoadPalette();
|
LoadPalette();
|
||||||
|
LoadMainColorMap();
|
||||||
Dictionary<string, TexturesParser> cachedparsers = new Dictionary<string, TexturesParser>(); //mxd
|
Dictionary<string, TexturesParser> cachedparsers = new Dictionary<string, TexturesParser>(); //mxd
|
||||||
int texcount = LoadTextures(texturesonly, texturenamesshorttofull, cachedparsers);
|
int texcount = LoadTextures(texturesonly, texturenamesshorttofull, cachedparsers);
|
||||||
int flatcount = LoadFlats(flatsonly, flatnamesshorttofull, 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
|
#endregion
|
||||||
|
|
||||||
#region ================== Colormaps
|
#region ================== Colormaps
|
||||||
|
|
|
@ -21,6 +21,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using CodeImp.DoomBuilder.Compilers;
|
using CodeImp.DoomBuilder.Compilers;
|
||||||
using CodeImp.DoomBuilder.Config;
|
using CodeImp.DoomBuilder.Config;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
using CodeImp.DoomBuilder.ZDoom;
|
using CodeImp.DoomBuilder.ZDoom;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -165,6 +166,8 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
// When implemented, this should find and load a PLAYPAL palette
|
// When implemented, this should find and load a PLAYPAL palette
|
||||||
public virtual Playpal LoadPalette() { return null; }
|
public virtual Playpal LoadPalette() { return null; }
|
||||||
|
|
||||||
|
public virtual ColorMap LoadMainColorMap(Playpal palette) { return null; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Colormaps
|
#region ================== Colormaps
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
public const int TEXTURE_INDEXED = 1;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
@ -61,6 +62,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
protected bool hasPatchWithSameName; //mxd
|
protected bool hasPatchWithSameName; //mxd
|
||||||
protected int namewidth; // biwa
|
protected int namewidth; // biwa
|
||||||
protected int shortnamewidth; // biwa
|
protected int shortnamewidth; // biwa
|
||||||
|
protected bool wantIndexed; // volte
|
||||||
|
|
||||||
//mxd. Hashing
|
//mxd. Hashing
|
||||||
private static int hashcounter;
|
private static int hashcounter;
|
||||||
|
@ -85,6 +87,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
private int mipmaplevels; // 0 = all mipmaps
|
private int mipmaplevels; // 0 = all mipmaps
|
||||||
protected bool dynamictexture;
|
protected bool dynamictexture;
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
|
private Texture indexedTexture;
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
protected bool isdisposed;
|
protected bool isdisposed;
|
||||||
|
@ -105,7 +108,8 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
|
public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd
|
||||||
internal bool HasLongName { get { return hasLongName; } } //mxd
|
internal bool HasLongName { get { return hasLongName; } } //mxd
|
||||||
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
|
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
|
public bool IsPreviewLoaded
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -176,6 +180,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
previewbitmap?.Dispose();
|
previewbitmap?.Dispose();
|
||||||
spritepreviewbitmap?.Dispose();
|
spritepreviewbitmap?.Dispose();
|
||||||
texture?.Dispose();
|
texture?.Dispose();
|
||||||
|
indexedTexture?.Dispose();
|
||||||
loadedbitmap = null;
|
loadedbitmap = null;
|
||||||
previewbitmap = null;
|
previewbitmap = null;
|
||||||
spritepreviewbitmap = null;
|
spritepreviewbitmap = null;
|
||||||
|
@ -330,6 +335,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
|
|
||||||
loadedbitmap?.Dispose();
|
loadedbitmap?.Dispose();
|
||||||
texture?.Dispose();
|
texture?.Dispose();
|
||||||
|
indexedTexture?.Dispose();
|
||||||
imagestate = ImageLoadState.Ready;
|
imagestate = ImageLoadState.Ready;
|
||||||
loadedbitmap = loadResult.bitmap;
|
loadedbitmap = loadResult.bitmap;
|
||||||
alphatest = loadResult.alphatest;
|
alphatest = loadResult.alphatest;
|
||||||
|
@ -676,13 +682,24 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
loadResult.bitmap.UnlockBits(bmpdata);
|
loadResult.bitmap.UnlockBits(bmpdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture GetTexture()
|
Texture GetTexture(bool indexed = false)
|
||||||
{
|
{
|
||||||
if (texture != null)
|
if (indexed && indexedTexture != null)
|
||||||
|
return indexedTexture;
|
||||||
|
if (!indexed && texture != null)
|
||||||
return texture;
|
return texture;
|
||||||
else if (imagestate == ImageLoadState.Loading)
|
|
||||||
|
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;
|
return General.Map.Data.LoadingTexture;
|
||||||
else if (loadfailed)
|
if (loadfailed)
|
||||||
return General.Map.Data.FailedTexture;
|
return General.Map.Data.FailedTexture;
|
||||||
|
|
||||||
if (imagestate == ImageLoadState.None)
|
if (imagestate == ImageLoadState.None)
|
||||||
|
@ -691,7 +708,18 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
return General.Map.Data.LoadingTexture;
|
return General.Map.Data.LoadingTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loadedbitmap == null)
|
||||||
|
{
|
||||||
|
return General.Map.Data.LoadingTexture;
|
||||||
|
}
|
||||||
|
|
||||||
texture = new Texture(General.Map.Graphics, loadedbitmap);
|
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.Dispose();
|
||||||
loadedbitmap = null;
|
loadedbitmap = null;
|
||||||
|
@ -699,7 +727,33 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
texture.Tag = name; //mxd. Helps with tracking undisposed resources...
|
texture.Tag = name; //mxd. Helps with tracking undisposed resources...
|
||||||
#endif
|
#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
|
// This updates a dynamic texture
|
||||||
|
@ -718,6 +772,8 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
{
|
{
|
||||||
texture?.Dispose();
|
texture?.Dispose();
|
||||||
texture = null;
|
texture = null;
|
||||||
|
indexedTexture?.Dispose();
|
||||||
|
indexedTexture = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This returns a preview image
|
// This returns a preview image
|
||||||
|
|
|
@ -152,6 +152,37 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
return palette;
|
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
|
#endregion
|
||||||
|
|
||||||
#region ================== Textures
|
#region ================== Textures
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
#region ================== Namespaces
|
#region ================== Namespaces
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using CodeImp.DoomBuilder.Rendering;
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
|
|
||||||
|
@ -84,6 +87,38 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
|
|
||||||
#region ================== Methods
|
#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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Config;
|
||||||
using CodeImp.DoomBuilder.Data.Scripting;
|
using CodeImp.DoomBuilder.Data.Scripting;
|
||||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||||
using CodeImp.DoomBuilder.IO;
|
using CodeImp.DoomBuilder.IO;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
using CodeImp.DoomBuilder.ZDoom;
|
using CodeImp.DoomBuilder.ZDoom;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -308,6 +309,21 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
return null; // No palette
|
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
|
#endregion
|
||||||
|
|
||||||
#region ================== Colormaps
|
#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>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -532,6 +532,9 @@
|
||||||
<data name="Sky" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<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>
|
<value>..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</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">
|
<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>
|
<value>..\Resources\Pin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -276,6 +277,12 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// This clamps a value between 0 and 1
|
||||||
private static float Saturate(float v)
|
private static float Saturate(float v)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#region ================== Namespaces
|
#region ================== Namespaces
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
using CodeImp.DoomBuilder.Map;
|
using CodeImp.DoomBuilder.Map;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
using CodeImp.DoomBuilder.VisualModes;
|
using CodeImp.DoomBuilder.VisualModes;
|
||||||
|
@ -46,6 +47,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
int CalculateBrightness(int level);
|
int CalculateBrightness(int level);
|
||||||
int CalculateBrightness(int level, Sidedef sd); //mxd
|
int CalculateBrightness(int level, Sidedef sd); //mxd
|
||||||
|
|
||||||
|
void SetClassicLightingColorMap(ColorMap colormap);
|
||||||
void SetHighlightedObject(IVisualPickable obj);
|
void SetHighlightedObject(IVisualPickable obj);
|
||||||
void AddSectorGeometry(VisualGeometry g);
|
void AddSectorGeometry(VisualGeometry g);
|
||||||
void AddThingGeometry(VisualThing t);
|
void AddThingGeometry(VisualThing t);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using CodeImp.DoomBuilder.Controls;
|
using CodeImp.DoomBuilder.Controls;
|
||||||
|
@ -70,6 +71,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
DeclareUniform(UniformName.lightsEnabled, "lightsEnabled", UniformType.Float);
|
DeclareUniform(UniformName.lightsEnabled, "lightsEnabled", UniformType.Float);
|
||||||
DeclareUniform(UniformName.slopeHandleLength, "slopeHandleLength", 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
|
// 2d fsaa
|
||||||
CompileShader(ShaderName.display2d_fsaa, "display2d.shader", "display2d_fsaa");
|
CompileShader(ShaderName.display2d_fsaa, "display2d.shader", "display2d_fsaa");
|
||||||
|
|
||||||
|
@ -91,6 +97,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
CompileShader(ShaderName.world3d_main_vertexcolor, "world3d.shader", "world3d_main_vertexcolor");
|
CompileShader(ShaderName.world3d_main_vertexcolor, "world3d.shader", "world3d_main_vertexcolor");
|
||||||
CompileShader(ShaderName.world3d_constant_color, "world3d.shader", "world3d_constant_color");
|
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
|
// skybox shader
|
||||||
CompileShader(ShaderName.world3d_skybox, "world3d_skybox.shader", "world3d_skybox");
|
CompileShader(ShaderName.world3d_skybox, "world3d_skybox.shader", "world3d_skybox");
|
||||||
|
|
||||||
|
@ -125,7 +135,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
Handle = RenderDevice_New(display, RenderTarget.Handle);
|
Handle = RenderDevice_New(display, RenderTarget.Handle);
|
||||||
if (Handle == IntPtr.Zero)
|
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; } }
|
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||||
|
@ -133,7 +147,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
void ThrowIfFailed(bool result)
|
void ThrowIfFailed(bool result)
|
||||||
{
|
{
|
||||||
if (!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()
|
public void Dispose()
|
||||||
|
@ -359,24 +377,24 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
RenderDevice_SetZWriteEnable(Handle, value);
|
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)
|
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);
|
static extern void RenderDevice_DeclareShader(IntPtr handle, ShaderName index, string name, string vertexShader, string fragShader);
|
||||||
|
|
||||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[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)]
|
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern bool RenderDevice_SetShader(IntPtr handle, ShaderName name);
|
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);
|
static extern void RenderDevice_SetZWriteEnable(IntPtr handle, bool value);
|
||||||
|
|
||||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
[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)]
|
[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)]
|
[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)]
|
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern bool RenderDevice_Draw(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount);
|
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_main_highlight_fog_vertexcolor,
|
||||||
world3d_vertex_color,
|
world3d_vertex_color,
|
||||||
world3d_constant_color,
|
world3d_constant_color,
|
||||||
world3d_slope_handle
|
world3d_slope_handle,
|
||||||
|
world3d_classic,
|
||||||
|
world3d_p19,
|
||||||
|
world3d_classic_highlight
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UniformType : int
|
public enum UniformType : int
|
||||||
|
@ -778,7 +799,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
fogcolor,
|
fogcolor,
|
||||||
sectorfogcolor,
|
sectorfogcolor,
|
||||||
lightsEnabled,
|
lightsEnabled,
|
||||||
slopeHandleLength
|
slopeHandleLength,
|
||||||
|
drawPaletted,
|
||||||
|
colormapSize,
|
||||||
|
lightLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VertexFormat : int { Flat, World }
|
public enum VertexFormat : int { Flat, World }
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
using CodeImp.DoomBuilder.Data;
|
using CodeImp.DoomBuilder.Data;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||||
|
@ -26,6 +27,7 @@ using CodeImp.DoomBuilder.GZBuilder.MD3;
|
||||||
using CodeImp.DoomBuilder.Map;
|
using CodeImp.DoomBuilder.Map;
|
||||||
using CodeImp.DoomBuilder.VisualModes;
|
using CodeImp.DoomBuilder.VisualModes;
|
||||||
using CodeImp.DoomBuilder.GZBuilder;
|
using CodeImp.DoomBuilder.GZBuilder;
|
||||||
|
using ColorMap = System.Drawing.Imaging.ColorMap;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -65,6 +67,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
private VisualVertexHandle vertexhandle;
|
private VisualVertexHandle vertexhandle;
|
||||||
private int[] lightOffsets;
|
private int[] lightOffsets;
|
||||||
|
|
||||||
|
private Data.ColorMap classicLightingColorMap = null;
|
||||||
|
private Texture classicLightingColorMapTex = null;
|
||||||
|
|
||||||
// Slope handle
|
// Slope handle
|
||||||
private VisualSlopeHandle visualslopehandle;
|
private VisualSlopeHandle visualslopehandle;
|
||||||
|
|
||||||
|
@ -135,6 +140,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public bool ShowSelection { get { return showselection; } set { showselection = value; } }
|
public bool ShowSelection { get { return showselection; } set { showselection = value; } }
|
||||||
public bool ShowHighlight { get { return showhighlight; } set { showhighlight = value; } }
|
public bool ShowHighlight { get { return showhighlight; } set { showhighlight = value; } }
|
||||||
|
|
||||||
|
protected bool UseIndexedTexture
|
||||||
|
{
|
||||||
|
get { return General.Settings.ClassicRendering && !fullbrightness; }
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Constructor / Disposer
|
#region ================== Constructor / Disposer
|
||||||
|
@ -294,6 +304,25 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
billboard = Matrix.RotationZ((float)(anglexy + Angle2D.PI));
|
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
|
// This creates 2D view matrix
|
||||||
private void CreateMatrices2D()
|
private void CreateMatrices2D()
|
||||||
{
|
{
|
||||||
|
@ -327,8 +356,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
graphics.SetUniform(UniformName.fogcolor, General.Colors.Background.ToColorValue());
|
graphics.SetUniform(UniformName.fogcolor, General.Colors.Background.ToColorValue());
|
||||||
graphics.SetUniform(UniformName.texturefactor, new Color4(1f, 1f, 1f, 1f));
|
graphics.SetUniform(UniformName.texturefactor, new Color4(1f, 1f, 1f, 1f));
|
||||||
graphics.SetUniform(UniformName.highlightcolor, new Color4()); //mxd
|
graphics.SetUniform(UniformName.highlightcolor, new Color4()); //mxd
|
||||||
TextureFilter texFilter = General.Settings.VisualBilinear ? TextureFilter.Linear : TextureFilter.Nearest;
|
TextureFilter texFilter = (!General.Settings.ClassicRendering && General.Settings.VisualBilinear) ? TextureFilter.Linear : TextureFilter.Nearest;
|
||||||
graphics.SetSamplerFilter(texFilter, texFilter, MipmapFilter.Linear, General.Settings.FilterAnisotropy);
|
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
|
// Texture addressing
|
||||||
graphics.SetSamplerState(TextureAddress.Wrap);
|
graphics.SetSamplerState(TextureAddress.Wrap);
|
||||||
|
@ -352,7 +383,18 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine shader pass to use
|
// 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
|
// Create crosshair vertices
|
||||||
if(crosshairverts == null)
|
if(crosshairverts == null)
|
||||||
|
@ -787,13 +829,24 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
bool hadlights = false;
|
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
|
// Render the geometry collected
|
||||||
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
|
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
|
||||||
{
|
{
|
||||||
curtexture = group.Key;
|
curtexture = group.Key;
|
||||||
|
|
||||||
// Apply texture
|
// Apply texture
|
||||||
graphics.SetTexture(curtexture.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
|
//mxd. Sort geometry by sector index
|
||||||
group.Value.Sort((g1, g2) => g1.Sector.Sector.FixedIndex - g2.Sector.Sector.FixedIndex);
|
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;
|
ShaderName wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||||
|
|
||||||
//mxd. Render fog?
|
//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;
|
wantedshaderpass += 8;
|
||||||
|
|
||||||
// Switch shader pass?
|
// Switch shader pass?
|
||||||
|
@ -896,6 +949,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// volte: set sector light level for classic rendering mode
|
||||||
|
graphics.SetUniform(UniformName.lightLevel, sector.Sector.Brightness);
|
||||||
|
|
||||||
//mxd. Set variables for fog rendering?
|
//mxd. Set variables for fog rendering?
|
||||||
if(wantedshaderpass > ShaderName.world3d_p7)
|
if(wantedshaderpass > ShaderName.world3d_p7)
|
||||||
{
|
{
|
||||||
|
@ -934,7 +990,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
curtexture = group.Key;
|
curtexture = group.Key;
|
||||||
|
|
||||||
// Apply texture
|
// Apply texture
|
||||||
graphics.SetTexture(curtexture.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
|
// Render all things with this texture
|
||||||
foreach(VisualThing t in group.Value)
|
foreach(VisualThing t in group.Value)
|
||||||
|
@ -958,20 +1016,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||||
|
|
||||||
//mxd. If fog is enagled, switch to shader, which calculates it
|
//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;
|
wantedshaderpass += 8;
|
||||||
|
|
||||||
//mxd. Create the matrix for positioning
|
//mxd. Create the matrix for positioning
|
||||||
world = CreateThingPositionMatrix(t);
|
world = CreateThingPositionMatrix(t);
|
||||||
|
|
||||||
//mxd. If current thing is light - set it's color to light color
|
//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
|
wantedshaderpass += 4; // Render using one of passes, which uses World3D.VertexColor
|
||||||
vertexcolor = t.LightColor;
|
vertexcolor = t.LightColor;
|
||||||
}
|
}
|
||||||
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
|
//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);
|
Color4 litcolor = GetLitColorForThing(t);
|
||||||
if(litcolor.ToArgb() != 0)
|
if(litcolor.ToArgb() != 0)
|
||||||
|
@ -1000,7 +1058,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the colors to use
|
// 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.vertexColor, vertexcolor);
|
||||||
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)));
|
graphics.SetUniform(UniformName.highlightcolor, CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)));
|
||||||
|
|
||||||
|
@ -1163,7 +1225,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
curtexture = g.Texture;
|
curtexture = g.Texture;
|
||||||
|
|
||||||
// Apply texture
|
// Apply texture
|
||||||
graphics.SetTexture(curtexture.Texture);
|
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||||
|
graphics.SetTexture(texture);
|
||||||
|
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||||
|
|
||||||
curtexturename = g.Texture.LongName;
|
curtexturename = g.Texture.LongName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1195,7 +1260,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
ShaderName wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
ShaderName wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||||
|
|
||||||
//mxd. Render fog?
|
//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;
|
wantedshaderpass += 8;
|
||||||
|
|
||||||
// Switch shader pass?
|
// Switch shader pass?
|
||||||
|
@ -1295,7 +1360,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
curtexture = t.Texture;
|
curtexture = t.Texture;
|
||||||
|
|
||||||
// Apply texture
|
// Apply texture
|
||||||
graphics.SetTexture(curtexture.Texture);
|
Texture texture = UseIndexedTexture ? curtexture.IndexedTexture : curtexture.Texture;
|
||||||
|
graphics.SetTexture(texture);
|
||||||
|
graphics.SetUniform(UniformName.drawPaletted, texture.UserData == ImageData.TEXTURE_INDEXED);
|
||||||
|
|
||||||
curtexturename = t.Texture.LongName;
|
curtexturename = t.Texture.LongName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,20 +1374,20 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
ShaderName wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||||
|
|
||||||
//mxd. if fog is enagled, switch to shader, which calculates it
|
//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;
|
wantedshaderpass += 8;
|
||||||
|
|
||||||
//mxd. Create the matrix for positioning
|
//mxd. Create the matrix for positioning
|
||||||
world = CreateThingPositionMatrix(t);
|
world = CreateThingPositionMatrix(t);
|
||||||
|
|
||||||
//mxd. If current thing is light - set it's color to light color
|
//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
|
wantedshaderpass += 4; // Render using one of passes, which uses World3D.VertexColor
|
||||||
vertexcolor = t.LightColor;
|
vertexcolor = t.LightColor;
|
||||||
}
|
}
|
||||||
//mxd. Check if Thing is affected by dynamic lights and set color accordingly
|
//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);
|
Color4 litcolor = GetLitColorForThing(t);
|
||||||
if(litcolor.ToArgb() != 0)
|
if(litcolor.ToArgb() != 0)
|
||||||
|
@ -1506,7 +1574,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
ShaderName wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
|
ShaderName wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
|
||||||
|
|
||||||
// If fog is enagled, switch to shader, which calculates it
|
// 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;
|
wantedshaderpass += 8;
|
||||||
|
|
||||||
// Switch shader pass?
|
// Switch shader pass?
|
||||||
|
|
|
@ -97,6 +97,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public TextureFormat Format { get; private set; }
|
public TextureFormat Format { get; private set; }
|
||||||
|
|
||||||
public object Tag { get; set; }
|
public object Tag { get; set; }
|
||||||
|
public int UserData { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CubeTexture : BaseTexture
|
public class CubeTexture : BaseTexture
|
||||||
|
|
|
@ -1330,6 +1330,16 @@ gztogglevisualvertices
|
||||||
default = 262230;
|
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
|
gztoggleenhancedrendering
|
||||||
{
|
{
|
||||||
title = "Toggle Enhanced Rendering Effects";
|
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 |
|
@ -16,6 +16,13 @@ uniforms
|
||||||
vec4 vertexColor;
|
vec4 vertexColor;
|
||||||
|
|
||||||
sampler2D texture1;
|
sampler2D texture1;
|
||||||
|
sampler2D texture2;
|
||||||
|
sampler2D texture3;
|
||||||
|
|
||||||
|
// classic lighting related
|
||||||
|
int drawPaletted;
|
||||||
|
ivec2 colormapSize;
|
||||||
|
int lightLevel;
|
||||||
|
|
||||||
// dynamic light related
|
// dynamic light related
|
||||||
vec4 lightPosAndRadius[64];
|
vec4 lightPosAndRadius[64];
|
||||||
|
@ -32,6 +39,59 @@ uniforms
|
||||||
|
|
||||||
functions
|
functions
|
||||||
{
|
{
|
||||||
|
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
|
// This adds fog color to current pixel color
|
||||||
vec4 getFogColor(vec3 PosW, vec4 color)
|
vec4 getFogColor(vec3 PosW, vec4 color)
|
||||||
{
|
{
|
||||||
|
@ -371,3 +431,66 @@ shader world3d_slope_handle extends world3d_vertex_color
|
||||||
v2f.UV = in.TextureCoordinate;
|
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.itemallmdl = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.itemtogglefog = new System.Windows.Forms.ToolStripMenuItem();
|
this.itemtogglefog = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.itemtogglesky = 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.itemtoggleeventlines = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.itemtogglevisualverts = new System.Windows.Forms.ToolStripMenuItem();
|
this.itemtogglevisualverts = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.buttonfullbrightness = new System.Windows.Forms.ToolStripButton();
|
this.buttonfullbrightness = new System.Windows.Forms.ToolStripButton();
|
||||||
|
@ -224,6 +225,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.modelsshowall = new System.Windows.Forms.ToolStripMenuItem();
|
this.modelsshowall = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.buttontogglefog = new System.Windows.Forms.ToolStripButton();
|
this.buttontogglefog = new System.Windows.Forms.ToolStripButton();
|
||||||
this.buttontogglesky = 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.buttontoggleeventlines = new System.Windows.Forms.ToolStripButton();
|
||||||
this.buttontogglevisualvertices = new System.Windows.Forms.ToolStripButton();
|
this.buttontogglevisualvertices = new System.Windows.Forms.ToolStripButton();
|
||||||
this.separatorgzmodes = new System.Windows.Forms.ToolStripSeparator();
|
this.separatorgzmodes = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
@ -798,6 +800,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.itemmodelmodes,
|
this.itemmodelmodes,
|
||||||
this.itemtogglefog,
|
this.itemtogglefog,
|
||||||
this.itemtogglesky,
|
this.itemtogglesky,
|
||||||
|
this.itemtoggleclassicrendering,
|
||||||
this.itemtoggleeventlines,
|
this.itemtoggleeventlines,
|
||||||
this.itemtogglevisualverts,
|
this.itemtogglevisualverts,
|
||||||
this.separatorhelpers,
|
this.separatorhelpers,
|
||||||
|
@ -1395,6 +1398,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.modelrendermode,
|
this.modelrendermode,
|
||||||
this.buttontogglefog,
|
this.buttontogglefog,
|
||||||
this.buttontogglesky,
|
this.buttontogglesky,
|
||||||
|
this.buttontoggleclassicrendering,
|
||||||
this.buttontoggleeventlines,
|
this.buttontoggleeventlines,
|
||||||
this.buttontogglevisualvertices,
|
this.buttontogglevisualvertices,
|
||||||
this.separatorgzmodes,
|
this.separatorgzmodes,
|
||||||
|
@ -1797,6 +1801,16 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.itemtogglesky.Text = "Render sky (Visual mode)";
|
this.itemtogglesky.Text = "Render sky (Visual mode)";
|
||||||
this.itemtogglesky.Click += new System.EventHandler(this.InvokeTaggedAction);
|
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
|
// itemeventlines
|
||||||
//
|
//
|
||||||
this.itemtoggleeventlines.CheckOnClick = true;
|
this.itemtoggleeventlines.CheckOnClick = true;
|
||||||
|
@ -2170,6 +2184,18 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.buttontogglesky.Text = "Render Sky (Visual mode)";
|
this.buttontogglesky.Text = "Render Sky (Visual mode)";
|
||||||
this.buttontogglesky.Click += new System.EventHandler(this.InvokeTaggedAction);
|
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
|
// buttontoggleeventlines
|
||||||
//
|
//
|
||||||
this.buttontoggleeventlines.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
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.ToolStripSeparator seperatorgeometry;
|
||||||
private System.Windows.Forms.ToolStripButton buttontogglefog;
|
private System.Windows.Forms.ToolStripButton buttontogglefog;
|
||||||
private System.Windows.Forms.ToolStripButton buttontogglesky;
|
private System.Windows.Forms.ToolStripButton buttontogglesky;
|
||||||
|
private System.Windows.Forms.ToolStripButton buttontoggleclassicrendering;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel warnsLabel;
|
private System.Windows.Forms.ToolStripStatusLabel warnsLabel;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemReloadModedef;
|
private System.Windows.Forms.ToolStripMenuItem itemReloadModedef;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemReloadGldefs;
|
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 itemallmdl;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemtogglefog;
|
private System.Windows.Forms.ToolStripMenuItem itemtogglefog;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemtogglesky;
|
private System.Windows.Forms.ToolStripMenuItem itemtogglesky;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem itemtoggleclassicrendering;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemtoggleeventlines;
|
private System.Windows.Forms.ToolStripMenuItem itemtoggleeventlines;
|
||||||
private System.Windows.Forms.ToolStripMenuItem itemtogglevisualverts;
|
private System.Windows.Forms.ToolStripMenuItem itemtogglevisualverts;
|
||||||
private ToolStripMenuItem itemimport;
|
private ToolStripMenuItem itemimport;
|
||||||
|
|
|
@ -2164,6 +2164,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
buttonsplitjoinedsectors.Checked = General.Settings.SplitJoinedSectors; //mxd
|
buttonsplitjoinedsectors.Checked = General.Settings.SplitJoinedSectors; //mxd
|
||||||
buttonautoclearsidetextures.Visible = General.Settings.ToolbarGeometry && maploaded; //mxd
|
buttonautoclearsidetextures.Visible = General.Settings.ToolbarGeometry && maploaded; //mxd
|
||||||
buttontest.Visible = General.Settings.ToolbarTesting && maploaded;
|
buttontest.Visible = General.Settings.ToolbarTesting && maploaded;
|
||||||
|
buttontoggleclassicrendering.Visible = General.Settings.ToolbarViewModes && maploaded;
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
modelrendermode.Visible = General.Settings.GZToolbarGZDoom && maploaded;
|
modelrendermode.Visible = General.Settings.GZToolbarGZDoom && maploaded;
|
||||||
|
@ -2330,6 +2331,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
|
|
||||||
buttontogglefog.Checked = General.Settings.GZDrawFog;
|
buttontogglefog.Checked = General.Settings.GZDrawFog;
|
||||||
buttontogglesky.Checked = General.Settings.GZDrawSky;
|
buttontogglesky.Checked = General.Settings.GZDrawSky;
|
||||||
|
buttontoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||||
buttontoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
buttontoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
||||||
buttontogglevisualvertices.Visible = General.Map.UDMF;
|
buttontogglevisualvertices.Visible = General.Map.UDMF;
|
||||||
buttontogglevisualvertices.Checked = General.Settings.GZShowVisualVertices;
|
buttontogglevisualvertices.Checked = General.Settings.GZShowVisualVertices;
|
||||||
|
@ -3141,6 +3143,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
itemtogglefixedthingsscale.Checked = General.Settings.FixedThingsScale; //mxd
|
itemtogglefixedthingsscale.Checked = General.Settings.FixedThingsScale; //mxd
|
||||||
itemtogglefog.Checked = General.Settings.GZDrawFog;
|
itemtogglefog.Checked = General.Settings.GZDrawFog;
|
||||||
itemtogglesky.Checked = General.Settings.GZDrawSky;
|
itemtogglesky.Checked = General.Settings.GZDrawSky;
|
||||||
|
itemtoggleclassicrendering.Checked = General.Settings.ClassicRendering;
|
||||||
itemtoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
itemtoggleeventlines.Checked = General.Settings.GZShowEventLines;
|
||||||
itemtogglevisualverts.Visible = (General.Map != null && General.Map.UDMF);
|
itemtogglevisualverts.Visible = (General.Map != null && General.Map.UDMF);
|
||||||
itemtogglevisualverts.Checked = General.Settings.GZShowVisualVertices;
|
itemtogglevisualverts.Checked = General.Settings.GZShowVisualVertices;
|
||||||
|
@ -3215,6 +3218,20 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
General.MainWindow.UpdateGZDoomPanel();
|
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")]
|
[BeginAction("gztoggleeventlines")]
|
||||||
internal void ToggleEventLines()
|
internal void ToggleEventLines()
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,9 +76,12 @@ extern "C"
|
||||||
Backend::Get()->DeleteRenderDevice(device);
|
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)
|
void RenderDevice_DeclareUniform(RenderDevice* device, UniformName name, const char* variablename, UniformType type)
|
||||||
|
@ -161,19 +164,19 @@ extern "C"
|
||||||
device->SetZWriteEnable(value);
|
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)
|
bool RenderDevice_Draw(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount)
|
||||||
|
|
|
@ -83,9 +83,9 @@ public:
|
||||||
virtual void SetMultisampleAntialias(bool value) = 0;
|
virtual void SetMultisampleAntialias(bool value) = 0;
|
||||||
virtual void SetZEnable(bool value) = 0;
|
virtual void SetZEnable(bool value) = 0;
|
||||||
virtual void SetZWriteEnable(bool value) = 0;
|
virtual void SetZWriteEnable(bool value) = 0;
|
||||||
virtual void SetTexture(Texture* texture) = 0;
|
virtual void SetTexture(int unit, Texture* texture) = 0;
|
||||||
virtual void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) = 0;
|
virtual void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) = 0;
|
||||||
virtual void SetSamplerState(TextureAddress address) = 0;
|
virtual void SetSamplerState(int unit, TextureAddress address) = 0;
|
||||||
virtual bool Draw(PrimitiveType type, int startIndex, int primitiveCount) = 0;
|
virtual bool Draw(PrimitiveType type, int startIndex, int primitiveCount) = 0;
|
||||||
virtual bool DrawIndexed(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;
|
virtual bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) = 0;
|
||||||
|
|
|
@ -113,16 +113,15 @@ GLRenderDevice::~GLRenderDevice()
|
||||||
glDeleteVertexArrays(1, &handle);
|
glDeleteVertexArrays(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : mSamplers)
|
for (auto& it : mTextureUnit)
|
||||||
{
|
|
||||||
for (GLuint handle : it.second.WrapModes)
|
|
||||||
{
|
{
|
||||||
|
GLuint &handle = it.SamplerHandle;
|
||||||
if (handle != 0)
|
if (handle != 0)
|
||||||
|
{
|
||||||
glDeleteSamplers(1, &handle);
|
glDeleteSamplers(1, &handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mShaderManager->ReleaseResources();
|
mShaderManager->ReleaseResources();
|
||||||
Context->ClearCurrent();
|
Context->ClearCurrent();
|
||||||
}
|
}
|
||||||
|
@ -264,27 +263,46 @@ 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;
|
mNeedApply = true;
|
||||||
mTexturesChanged = 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;
|
bool dirty = false;
|
||||||
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];
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mTextureUnit[unit].MaxAnisotropy != maxanisotropy)
|
||||||
|
{
|
||||||
|
mTextureUnit[unit].MaxAnisotropy = maxanisotropy;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty)
|
||||||
|
{
|
||||||
mNeedApply = true;
|
mNeedApply = true;
|
||||||
mTexturesChanged = true;
|
mTexturesChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
mNeedApply = true;
|
||||||
mTexturesChanged = true;
|
mTexturesChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -901,42 +928,47 @@ bool GLRenderDevice::ApplyUniforms()
|
||||||
|
|
||||||
bool GLRenderDevice::ApplyTextures()
|
bool GLRenderDevice::ApplyTextures()
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
bool hasError = false;
|
||||||
if (mTextureUnit.Tex)
|
for (int index = 0; index < 10; index++)
|
||||||
{
|
{
|
||||||
GLenum target = mTextureUnit.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
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, mTextureUnit.Tex->GetTexture(this));
|
glBindTexture(target, unit.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)
|
if (samplerHandle == 0)
|
||||||
{
|
{
|
||||||
static const int wrapMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE };
|
static const int wrapMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE };
|
||||||
|
|
||||||
glGenSamplers(1, &samplerHandle);
|
glGenSamplers(1, &samplerHandle);
|
||||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, mSamplerFilterKey.MinFilter);
|
glSamplerParameteri(samplerHandle, GL_TEXTURE_MIN_FILTER, key.MinFilter);
|
||||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, mSamplerFilterKey.MagFilter);
|
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, key.MagFilter);
|
||||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrapMode[(int)mTextureUnit.WrapMode]);
|
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_S, wrapMode[(int)unit.WrapMode]);
|
||||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrapMode[(int)mTextureUnit.WrapMode]);
|
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_T, wrapMode[(int)unit.WrapMode]);
|
||||||
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrapMode[(int)mTextureUnit.WrapMode]);
|
glSamplerParameteri(samplerHandle, GL_TEXTURE_WRAP_R, wrapMode[(int)unit.WrapMode]);
|
||||||
if (mSamplerFilterKey.MaxAnisotropy > 0.0f)
|
if (key.MaxAnisotropy > 0.0f)
|
||||||
glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, mSamplerFilterKey.MaxAnisotropy);
|
glSamplerParameterf(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, key.MaxAnisotropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTextureUnit.SamplerHandle != samplerHandle)
|
if (unit.SamplerHandle != samplerHandle)
|
||||||
{
|
{
|
||||||
mTextureUnit.SamplerHandle = samplerHandle;
|
unit.SamplerHandle = samplerHandle;
|
||||||
glBindSampler(0, samplerHandle);
|
glBindSampler(index, samplerHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
hasError |= CheckGLError();
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mTexturesChanged = false;
|
mTexturesChanged = false;
|
||||||
|
return hasError;
|
||||||
return CheckGLError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mutex& GLRenderDevice::GetMutex()
|
std::mutex& GLRenderDevice::GetMutex()
|
||||||
|
|
|
@ -54,9 +54,9 @@ public:
|
||||||
void SetMultisampleAntialias(bool value) override;
|
void SetMultisampleAntialias(bool value) override;
|
||||||
void SetZEnable(bool value) override;
|
void SetZEnable(bool value) override;
|
||||||
void SetZWriteEnable(bool value) override;
|
void SetZWriteEnable(bool value) override;
|
||||||
void SetTexture(Texture* texture) override;
|
void SetTexture(int unit, Texture* texture) override;
|
||||||
void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) override;
|
void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) override;
|
||||||
void SetSamplerState(TextureAddress address) override;
|
void SetSamplerState(int unit, TextureAddress address) override;
|
||||||
bool Draw(PrimitiveType type, int startIndex, int primitiveCount) override;
|
bool Draw(PrimitiveType type, int startIndex, int primitiveCount) override;
|
||||||
bool DrawIndexed(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;
|
bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) override;
|
||||||
|
@ -120,7 +120,11 @@ public:
|
||||||
GLTexture* Tex = nullptr;
|
GLTexture* Tex = nullptr;
|
||||||
TextureAddress WrapMode = TextureAddress::Wrap;
|
TextureAddress WrapMode = TextureAddress::Wrap;
|
||||||
GLuint SamplerHandle = 0;
|
GLuint SamplerHandle = 0;
|
||||||
} mTextureUnit;
|
TextureFilter MinFilter = TextureFilter::Nearest;
|
||||||
|
TextureFilter MagFilter = TextureFilter::Nearest;
|
||||||
|
MipmapFilter MipFilter = MipmapFilter::None;
|
||||||
|
float MaxAnisotropy = 1;
|
||||||
|
} mTextureUnit[10];
|
||||||
|
|
||||||
struct SamplerFilterKey
|
struct SamplerFilterKey
|
||||||
{
|
{
|
||||||
|
@ -139,8 +143,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<SamplerFilterKey, SamplerFilter> mSamplers;
|
std::map<SamplerFilterKey, SamplerFilter> mSamplers;
|
||||||
SamplerFilterKey mSamplerFilterKey;
|
|
||||||
SamplerFilter* mSamplerFilter = nullptr;
|
SamplerFilterKey GetSamplerFilterKey(TextureFilter filter, MipmapFilter mipFilter, float maxAnisotropy);
|
||||||
|
|
||||||
int mVertexBuffer = -1;
|
int mVertexBuffer = -1;
|
||||||
int64_t mVertexBufferStartIndex = 0;
|
int64_t mVertexBufferStartIndex = 0;
|
||||||
|
|
|
@ -41,6 +41,8 @@ bool GLShader::CheckCompile(GLRenderDevice* device)
|
||||||
CreateProgram(device);
|
CreateProgram(device);
|
||||||
glUseProgram(mProgram);
|
glUseProgram(mProgram);
|
||||||
glUniform1i(glGetUniformLocation(mProgram, "texture1"), 0);
|
glUniform1i(glGetUniformLocation(mProgram, "texture1"), 0);
|
||||||
|
glUniform1i(glGetUniformLocation(mProgram, "texture2"), 1);
|
||||||
|
glUniform1i(glGetUniformLocation(mProgram, "texture3"), 2);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,11 @@
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
|
@ -1614,6 +1614,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// This draws a frame
|
// This draws a frame
|
||||||
public override void OnRedrawDisplay()
|
public override void OnRedrawDisplay()
|
||||||
{
|
{
|
||||||
|
renderer.SetClassicLightingColorMap(General.Map.Data.MainColorMap);
|
||||||
|
|
||||||
// Start drawing
|
// Start drawing
|
||||||
if(renderer.Start())
|
if(renderer.Start())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue