Merge branch 'master' into visual-slope2

This commit is contained in:
biwa 2020-03-17 22:10:04 +01:00
commit 7b0adadbfb
64 changed files with 1560 additions and 1566 deletions

View file

@ -0,0 +1,68 @@
name: Continuous Integration - Other
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- {
name: "macOS",
os: macos-latest
}
- {
name: "Linux",
os: ubuntu-latest
}
steps:
- uses: actions/checkout@v1
- name: Build
run: |
if [[ "${{ runner.os }}" == 'macOS' ]]; then
make mac
elif [[ "${{ runner.os }}" == 'Linux' ]]; then
sudo apt install mesa-common-dev
make linux
fi
- name: Test Files Presence
run: |
FILES=( \
Build/Builder.exe \
Build/libBuilderNative.so \
Build/Plugins/AutomapMode.dll \
Build/Plugins/BuilderEffects.dll \
Build/Plugins/BuilderModes.dll \
Build/Plugins/ColorPicker.dll \
Build/Plugins/CommentsPanel.dll \
Build/Plugins/NodesViewer.dll \
Build/Plugins/SoundPropagationMode.dll \
Build/Plugins/StairSectorBuilder.dll \
Build/Plugins/TagExplorer.dll \
Build/Plugins/TagRange.dll \
Build/Plugins/ThreeDFloorMode.dll \
Build/Plugins/VisplaneExplorer.dll \
)
for filename in "${FILES[@]}"; do
if [ ! -f $filename ]; then
echo "ERROR: File $filename is missing"
exit 1
fi
done
- name: Prepare Package
run: |
# Delete unwanted files
rm -r Build/Setup
- name: Upload Package
uses: actions/upload-artifact@v1
with:
path: Build
name: "UDB_${{ matrix.config.name }}"

View file

@ -1,4 +1,4 @@
name: Continuous Integration
name: Continuous Integration - Windows
on: [push, pull_request]

View file

@ -65,4 +65,11 @@ nodebuilders
compiler = "zdbsp";
parameters = "-z -X -o%FO %FI";
}
zdbsp_udmf_compressed_huge
{
title = "ZDBSP - Compress nodes (UDMF) (Large Maps)";
compiler = "zdbsp";
parameters = "-z -X -s016 -p128 -d032 -G -5 -o%FO %FI";
}
}

View file

@ -30,6 +30,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StairSectorBuilder", "Sourc
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomapMode", "Source\Plugins\AutomapMode\AutomapModeMono.csproj", "{B33F68D5-1335-400C-A1D7-7F5602A030EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThreeDFloorMode", "Source\Plugins\3DFloorMode\ThreeDFloorModeMono.csproj", "{88CFD996-027B-4CBE-9828-26B2728B6127}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug + Profiler|x64 = Debug + Profiler|x64
@ -234,6 +236,22 @@ Global
{B33F68D5-1335-400C-A1D7-7F5602A030EF}.Release|x64.Build.0 = Release|x64
{B33F68D5-1335-400C-A1D7-7F5602A030EF}.Release|x86.ActiveCfg = Release|x86
{B33F68D5-1335-400C-A1D7-7F5602A030EF}.Release|x86.Build.0 = Release|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug + Profiler|x64.ActiveCfg = Debug|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug + Profiler|x64.Build.0 = Debug|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug + Profiler|x86.ActiveCfg = Debug|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug + Profiler|x86.Build.0 = Debug|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug|x64.ActiveCfg = Debug|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug|x64.Build.0 = Debug|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug|x86.ActiveCfg = Debug|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Debug|x86.Build.0 = Debug|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release + Profiler|x64.ActiveCfg = Release|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release + Profiler|x64.Build.0 = Release|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release + Profiler|x86.ActiveCfg = Release|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release + Profiler|x86.Build.0 = Release|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release|x64.ActiveCfg = Release|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release|x64.Build.0 = Release|x64
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release|x86.ActiveCfg = Release|x86
{88CFD996-027B-4CBE-9828-26B2728B6127}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Binary file not shown.

Binary file not shown.

View file

@ -549,7 +549,6 @@
<Compile Include="IO\Lump.cs" />
<Compile Include="IO\MapSetIO.cs" />
<Compile Include="IO\UniversalMapSetIO.cs" />
<Compile Include="IO\UnknownImageReader.cs" />
<Compile Include="IO\WAD.cs" />
<Compile Include="Windows\MainForm.cs">
<SubType>Form</SubType>

View file

@ -539,7 +539,6 @@
<Compile Include="IO\Lump.cs" />
<Compile Include="IO\MapSetIO.cs" />
<Compile Include="IO\UniversalMapSetIO.cs" />
<Compile Include="IO\UnknownImageReader.cs" />
<Compile Include="IO\WAD.cs" />
<Compile Include="Windows\MainForm.cs">
<SubType>Form</SubType>

View file

@ -229,7 +229,7 @@ namespace CodeImp.DoomBuilder.Controls
if(thinginfo.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) &&
(thinginfo.Sprite.Length > DataManager.INTERNAL_PREFIX.Length))
{
spritetex.Image = General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetBitmap();
spritetex.Image = General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetSpritePreview();
return;
}

View file

@ -118,7 +118,7 @@ namespace CodeImp.DoomBuilder.Controls
if(ti.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) && (ti.Sprite.Length > DataManager.INTERNAL_PREFIX.Length))
{
spritename.Text = "";
spritetex.Image = General.Map.Data.GetSpriteImage(ti.Sprite).GetBitmap();
spritetex.Image = General.Map.Data.GetSpriteImage(ti.Sprite).GetSpritePreview();
}
else if((ti.Sprite.Length <= 8) && (ti.Sprite.Length > 0))
{

View file

@ -62,19 +62,11 @@ namespace CodeImp.DoomBuilder.Data
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMCOLORMAP, General.Map.Data.Palette);
if(reader is UnknownImageReader)
bitmap = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMCOLORMAP, General.Map.Data.Palette);
if(bitmap == null)
{
// Data is in an unknown format!
error = "Colormap lump \"" + Name + "\" data format could not be read. Does this lump contain valid colormap data at all?";
bitmap = null;
}
else
{
// Read data as bitmap
mem.Seek(0, SeekOrigin.Begin);
if(bitmap != null) bitmap.Dispose();
bitmap = reader.ReadAsBitmap(mem);
}
// Done

View file

@ -102,8 +102,6 @@ namespace CodeImp.DoomBuilder.Data
private object syncobject = new object();
private Queue<ImageData> imageque;
private Thread[] backgroundloader;
private int threadsfinished;
private bool notifiedbusy;
// Special images
private ImageData missingtexture3d;
@ -134,10 +132,6 @@ namespace CodeImp.DoomBuilder.Data
private List<ThingCategory> thingcategories;
private Dictionary<int, ThingTypeInfo> thingtypes;
// Timing
private long loadstarttime;
private long loadfinishtime;
// Disposing
private bool isdisposed;
@ -235,16 +229,12 @@ namespace CodeImp.DoomBuilder.Data
// Load special images (mxd: the rest is loaded in LoadInternalTextures())
whitetexture = new ResourceImage("CodeImp.DoomBuilder.Resources.White.png") { UseColorCorrection = false };
whitetexture.LoadImage();
blacktexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Black.png") { UseColorCorrection = false }; //mxd
blacktexture.LoadImage(); //mxd
unknownimage = new UnknownImage(Properties.Resources.UnknownImage); //mxd. There should be only one!
unknownimage = new UnknownImage(); //mxd. There should be only one!
//mxd. Textures browser images
foldertexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Folder96.png") { UseColorCorrection = false };
foldertexture.LoadImage();
folderuptexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Folder96Up.png") { UseColorCorrection = false };
folderuptexture.LoadImage();
//mxd. Create comment icons
commenttextures = new ImageData[]
@ -255,12 +245,6 @@ namespace CodeImp.DoomBuilder.Data
new ResourceImage("CodeImp.DoomBuilder.Resources.CommentProblem.png") { UseColorCorrection = false },
new ResourceImage("CodeImp.DoomBuilder.Resources.CommentSmile.png") { UseColorCorrection = false },
};
//mxd. Load comment icons
foreach(ImageData data in commenttextures)
{
data.LoadImage();
}
}
// Disposer
@ -660,12 +644,6 @@ namespace CodeImp.DoomBuilder.Data
imageque = null;
mapinfo = null; //mxd
}
//mxd. Called before Clock is reset
internal void OnBeforeClockReset()
{
if(loadstarttime > 0) loadstarttime -= Clock.CurrentTime;
}
#endregion
@ -717,11 +695,6 @@ namespace CodeImp.DoomBuilder.Data
// This starts background loading
private void StartBackgroundLoader()
{
// Timing
loadstarttime = Clock.CurrentTime;
loadfinishtime = 0;
threadsfinished = 0;
// If a loader is already running, stop it first
if(backgroundloader != null) StopBackgroundLoader();
@ -756,7 +729,6 @@ namespace CodeImp.DoomBuilder.Data
}
// Done
notifiedbusy = false;
backgroundloader = null;
General.MainWindow.UpdateStatus();
}
@ -770,85 +742,21 @@ namespace CodeImp.DoomBuilder.Data
// Wait a bit before loading to give the main thread a headstart on acquiring the locks in the resource loader part of the codebase..
Thread.Sleep(666);
do
while (true)
{
// Get next item
ImageData image = null;
lock(syncobject)
{
// Fetch next image to process
if(imageque.Count > 0) image = imageque.Dequeue();
}
// Any image to process?
if(image != null)
{
image.LoadImage();
}
// Doing something?
if(image != null)
{
// Wait a bit and update icon
if(!notifiedbusy)
{
notifiedbusy = true;
General.MainWindow.UpdateStatus();
}
}
else
{
bool lastthread = false;
lock (syncobject)
{
threadsfinished++;
if (threadsfinished == backgroundloader.Length)
lastthread = true;
}
if (lastthread)
{
// Timing
if (loadfinishtime == 0)
{
//mxd. Release PK3 files
foreach (DataReader reader in containers)
{
if (reader is PK3Reader) (reader as PK3Reader).BatchMode = false;
}
loadfinishtime = Clock.CurrentTime;
string deltatimesec = ((loadfinishtime - loadstarttime) / 1000.0f).ToString("########0.00");
General.WriteLogLine("Resources loading took " + deltatimesec + " seconds");
loadstarttime = 0; //mxd
lock (syncobject)
{
threadsfinished = 0;
}
//mxd. Show more detailed message
if (notifiedbusy)
{
notifiedbusy = false;
General.MainWindow.ResourcesLoaded(deltatimesec);
}
}
else if (notifiedbusy) //mxd. Sould never happen (?)
{
notifiedbusy = false;
General.MainWindow.UpdateStatus();
}
}
// Wait until there's more to do.
lock (syncobject)
{
if (imageque.Count == 0) Monitor.Wait(syncobject);
}
if(imageque.Count > 0)
image = imageque.Dequeue();
else
Monitor.Wait(syncobject);
}
image?.BackgroundLoadImage();
}
while (true);
}
catch(ThreadInterruptedException) { }
}
@ -867,7 +775,7 @@ namespace CodeImp.DoomBuilder.Data
}
}
void QueueLoadPreview(ImageData img)
internal void QueueLoadPreview(ImageData img)
{
if (img.PreviewState == ImageLoadState.None)
{
@ -944,8 +852,6 @@ namespace CodeImp.DoomBuilder.Data
list.Remove(img.LongName);
list.Add(img.LongName, img);
counter++;
QueueLoadPreview(img);
}
}
}
@ -1012,8 +918,6 @@ namespace CodeImp.DoomBuilder.Data
{
nametranslation.Remove(img.LongName);
}
QueueLoadPreview(img);
}
}
}
@ -1097,11 +1001,11 @@ namespace CodeImp.DoomBuilder.Data
if(!(img is UnknownImage))
{
if(!img.IsImageLoaded) img.LoadImage();
img.LoadImageNow();
if(!img.LoadFailed)
{
// HiResImage will not give us it's actual scale
Bitmap texture = img.GetBitmap();
Bitmap texture = img.GetSkyboxBitmap();
lock (texture)
{
scale = new Vector2D((float)img.Width / texture.Width, (float)img.Height / texture.Height);
@ -1131,22 +1035,8 @@ namespace CodeImp.DoomBuilder.Data
if(mem == null) continue;
// Is it an image?
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(!(reader is UnknownImageReader))
{
// Load the image
mem.Seek(0, SeekOrigin.Begin);
Bitmap result;
try { result = reader.ReadAsBitmap(mem); }
catch(InvalidDataException)
{
// Data cannot be read!
result = null;
}
// Found it?
if(result != null) return result;
}
Bitmap bitmap = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(bitmap != null) return bitmap;
}
// No such image found
@ -1197,14 +1087,14 @@ namespace CodeImp.DoomBuilder.Data
if(File.Exists(path))
{
result = new FileImage(name, path) { AllowUnload = false };
}
else
result.LoadImageNow();
}
else
{
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load editor texture \"" + name + "\". Using built-in one instead.");
result = new ResourceImage("CodeImp.DoomBuilder.Resources." + name);
}
result.LoadImage();
return result;
}
@ -1243,8 +1133,6 @@ namespace CodeImp.DoomBuilder.Data
{
nametranslation.Remove(img.LongName);
}
QueueLoadPreview(img);
}
}
}
@ -1373,7 +1261,6 @@ namespace CodeImp.DoomBuilder.Data
textures[img.LongName] = replacer;
//replaced = true;
QueueLoadPreview(img);
counter++;
}
@ -1386,7 +1273,6 @@ namespace CodeImp.DoomBuilder.Data
flats[img.LongName] = replacer;
//replaced = true;
QueueLoadPreview(img);
counter++;
}
@ -1398,7 +1284,6 @@ namespace CodeImp.DoomBuilder.Data
sprites[img.LongName] = replacer;
//replaced = true;
QueueLoadPreview(img);
counter++;
}
@ -1522,8 +1407,6 @@ namespace CodeImp.DoomBuilder.Data
// Add to collection
sprites.Add(image.LongName, image);
QueueLoadPreview(image);
}
}
else
@ -1569,8 +1452,6 @@ namespace CodeImp.DoomBuilder.Data
{
image = sprites[info.SpriteLongName];
}
if (image != null) QueueLoadPreview(image);
}
}
}
@ -1628,7 +1509,7 @@ namespace CodeImp.DoomBuilder.Data
foreach(string spritefile in files)
{
ImageData img = new FileImage(Path.GetFileNameWithoutExtension(spritefile).ToLowerInvariant(), spritefile);
img.LoadImage();
img.LoadImageNow();
img.AllowUnload = false;
name = INTERNAL_PREFIX + img.Name;
long hash = Lump.MakeLongName(name, true); //mxd
@ -1642,7 +1523,6 @@ namespace CodeImp.DoomBuilder.Data
if(!internalspriteslookup.ContainsKey(name))
{
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.Nothing.png");
img.LoadImage();
img.AllowUnload = false;
long hash = Lump.MakeLongName(name, true); //mxd
sprites[hash] = img; //mxd
@ -1654,7 +1534,6 @@ namespace CodeImp.DoomBuilder.Data
if(!internalspriteslookup.ContainsKey(name))
{
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.UnknownThing.png");
img.LoadImage();
img.AllowUnload = false;
sprites[UNKNOWN_THING] = img; //mxd
internalspriteslookup[name] = UNKNOWN_THING; //mxd
@ -1666,7 +1545,6 @@ namespace CodeImp.DoomBuilder.Data
if(!internalspriteslookup.ContainsKey(name))
{
ImageData img = new ResourceImage("CodeImp.DoomBuilder.Resources.MissingThing.png");
img.LoadImage();
img.AllowUnload = false;
sprites[MISSING_THING] = img; //mxd
internalspriteslookup[name] = MISSING_THING; //mxd
@ -1688,7 +1566,6 @@ namespace CodeImp.DoomBuilder.Data
if (img != null)
{
img.UsedInMap = true;
QueueLoadImage(img);
}
return img;
}
@ -1705,7 +1582,6 @@ namespace CodeImp.DoomBuilder.Data
if (img != null)
{
img.UsedInMap = true;
QueueLoadImage(img);
}
return img;
}
@ -1739,7 +1615,6 @@ namespace CodeImp.DoomBuilder.Data
if (image != null)
{
image.UsedInMap = true;
QueueLoadImage(image);
}
return image;
}
@ -1754,7 +1629,6 @@ namespace CodeImp.DoomBuilder.Data
if (img != null)
{
img.UsedInMap = true;
QueueLoadImage(img);
}
return img;
}
@ -2416,8 +2290,6 @@ namespace CodeImp.DoomBuilder.Data
// Add to collection
sprites.Add(sprite.LongName, sprite);
QueueLoadPreview(sprite);
}
// Apply VOXELDEF settings to the preview image...
@ -2783,8 +2655,6 @@ namespace CodeImp.DoomBuilder.Data
textures[camteximage.LongName] = camteximage;
flats[camteximage.LongName] = camteximage;
QueueLoadPreview(camteximage);
// Add to container's texture set
currentreader.TextureSet.AddFlat(camteximage);
currentreader.TextureSet.AddTexture(camteximage);
@ -3143,7 +3013,6 @@ namespace CodeImp.DoomBuilder.Data
if (i.Value.LoadFailed)
continue;
i.Value.UsedInMap = usedtextures.ContainsKey(i.Key);
QueueLoadImage(i.Value);
}
// Set used on all flats
@ -3152,7 +3021,6 @@ namespace CodeImp.DoomBuilder.Data
if (i.Value.LoadFailed)
continue;
i.Value.UsedInMap = usedtextures.ContainsKey(i.Key);
QueueLoadImage(i.Value);
}
}
//mxd. Use separate collections
@ -3164,7 +3032,6 @@ namespace CodeImp.DoomBuilder.Data
if (i.Value.LoadFailed)
continue;
i.Value.UsedInMap = usedtextures.ContainsKey(i.Key);
QueueLoadImage(i.Value);
}
// Set used on all flats
@ -3173,7 +3040,6 @@ namespace CodeImp.DoomBuilder.Data
if (i.Value.LoadFailed)
continue;
i.Value.UsedInMap = usedflats.ContainsKey(i.Key);
QueueLoadImage(i.Value);
}
}
@ -3255,7 +3121,7 @@ namespace CodeImp.DoomBuilder.Data
// Use the built-in texture
ImageData tex = LoadInternalTexture("MissingSky3D.png");
Bitmap bmp = tex.GetBitmap();
Bitmap bmp = tex.GetSkyboxBitmap();
Bitmap sky;
lock (bmp)
{
@ -3363,7 +3229,7 @@ namespace CodeImp.DoomBuilder.Data
// Make custom rendertarget
const int cubemaptexsize = 1024;
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize);
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize, TextureFormat.Rgba8);
// Start rendering
General.Map.Graphics.StartRendering(true, new Color4(), rendertarget, true);

View file

@ -160,18 +160,7 @@ namespace CodeImp.DoomBuilder.Data
if (filedata != null)
{
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette);
if (!(reader is UnknownImageReader))
{
// Load the image
filedata.Seek(0, SeekOrigin.Begin);
try { bitmap = reader.ReadAsBitmap(filedata); }
catch (InvalidDataException)
{
// Data cannot be read!
bitmap = null;
}
}
bitmap = ImageDataFormat.TryLoadImage(filedata, probableformat, General.Map.Data.Palette);
// Not loaded?
if (bitmap == null)

View file

@ -69,18 +69,11 @@ namespace CodeImp.DoomBuilder.Data
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
if(reader is UnknownImageReader)
bitmap = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
if(bitmap == null)
{
// Data is in an unknown format!
error = "Flat lump \"" + Path.Combine(flatlocation, Name) + "\" data format could not be read. Does this lump contain valid picture data at all?";
bitmap = null;
}
else
{
// Read data as bitmap
mem.Seek(0, SeekOrigin.Begin);
bitmap = reader.ReadAsBitmap(mem);
}
// Done

View file

@ -98,7 +98,7 @@ namespace CodeImp.DoomBuilder.Data
hasLongName = overridden.HasLongName;
overridesettingsapplied = true;
if(!overridden.IsImageLoaded) overridden.LoadImage();
overridden.LoadImageNow();
if(overridden.ImageState == ImageLoadState.Ready)
{
// Store source properteis
@ -129,19 +129,7 @@ namespace CodeImp.DoomBuilder.Data
MemoryStream mem = new MemoryStream(membytes);
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, (isFlat ? ImageDataFormat.DOOMFLAT : ImageDataFormat.DOOMPICTURE), General.Map.Data.Palette);
if(!(reader is UnknownImageReader))
{
// Load the image
mem.Seek(0, SeekOrigin.Begin);
try { bitmap = reader.ReadAsBitmap(mem); }
catch(InvalidDataException)
{
// Data cannot be read!
bitmap = null;
}
}
bitmap = ImageDataFormat.TryLoadImage(mem, (isFlat ? ImageDataFormat.DOOMFLAT : ImageDataFormat.DOOMPICTURE), General.Map.Data.Palette);
// Not loaded?
if(bitmap == null)

View file

@ -17,6 +17,7 @@
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
@ -70,9 +71,15 @@ namespace CodeImp.DoomBuilder.Data
private ImageLoadState imagestate;
private bool loadfailed;
// Alpha test
private BitArray alphatest;
private int alphatestWidth = 64;
private int alphatestHeight = 64;
// GDI bitmap
private Bitmap bitmap;
private Bitmap loadedbitmap;
private Bitmap previewbitmap;
private Bitmap spritepreviewbitmap;
// Direct3D texture
private int mipmaplevels; // 0 = all mipmaps
@ -99,8 +106,27 @@ namespace CodeImp.DoomBuilder.Data
internal bool HasLongName { get { return hasLongName; } } //mxd
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
public Texture Texture { get { return GetTexture(); } }
public bool IsPreviewLoaded { get { return (previewstate == ImageLoadState.Ready); } }
public bool IsImageLoaded { get { return (imagestate == ImageLoadState.Ready); } }
public bool IsPreviewLoaded
{
get
{
if (previewstate == ImageLoadState.None)
General.Map.Data.QueueLoadPreview(this);
return (previewstate == ImageLoadState.Ready);
}
}
public bool IsImageLoaded
{
get
{
if (imagestate == ImageLoadState.None)
General.Map.Data.QueueLoadImage(this);
return (imagestate == ImageLoadState.Ready);
}
}
public bool LoadFailed { get { return loadfailed; } }
public bool IsDisposed { get { return isdisposed; } }
public bool AllowUnload { get; set; }
@ -145,10 +171,14 @@ namespace CodeImp.DoomBuilder.Data
// Not already disposed?
if(!isdisposed)
{
// Clean up
bitmap?.Dispose();
texture?.Dispose();
bitmap = null;
// Clean up
loadedbitmap?.Dispose();
previewbitmap?.Dispose();
spritepreviewbitmap?.Dispose();
texture?.Dispose();
loadedbitmap = null;
previewbitmap = null;
spritepreviewbitmap = null;
texture = null;
// Done
@ -185,16 +215,45 @@ namespace CodeImp.DoomBuilder.Data
shortnamewidth = (int)Math.Ceiling(General.Interface.MeasureString(shortname, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width) + 6;
}
// This returns the bitmap image
public Bitmap GetBitmap()
{
// Image loaded successfully?
if(!loadfailed && (imagestate == ImageLoadState.Ready) && (bitmap != null))
return bitmap;
// Image loading failed?
return (loadfailed ? Properties.Resources.Failed : Properties.Resources.Hourglass);
}
public int GetAlphaTestWidth()
{
return alphatestWidth;
}
public int GetAlphaTestHeight()
{
return alphatestHeight;
}
public bool AlphaTestPixel(int x, int y)
{
if (alphatest != null)
return alphatest.Get(x + y * alphatestWidth);
else
return true;
}
public Image GetBackgroundBitmap()
{
return LocalGetBitmap();
}
public Bitmap GetSkyboxBitmap()
{
return LocalGetBitmap();
}
public Bitmap ExportBitmap()
{
return LocalGetBitmap();
}
public Bitmap GetSpritePreview()
{
if (spritepreviewbitmap == null)
spritepreviewbitmap = LocalGetBitmap();
return spritepreviewbitmap;
}
// Loads the image directly. This is needed by the background loader for some patches.
public Bitmap LocalGetBitmap()
@ -211,13 +270,22 @@ namespace CodeImp.DoomBuilder.Data
return result.bitmap;
}
public void LoadImage()
public void LoadImageNow()
{
if (imagestate != ImageLoadState.Ready)
{
imagestate = ImageLoadState.Loading;
LoadImage(true);
}
}
internal void BackgroundLoadImage()
{
LoadImage(true);
}
// This loads the image
public virtual void LoadImage(bool notify)
protected void LoadImage(bool notify)
{
if (imagestate == ImageLoadState.Ready && previewstate != ImageLoadState.Loading)
return;
@ -227,18 +295,20 @@ namespace CodeImp.DoomBuilder.Data
ConvertImageFormat(loadResult);
MakeImagePreview(loadResult);
MakeAlphaTestImage(loadResult);
// Save memory by disposing the original image immediately if we only used it to load a preview image
bool onlyPreview = false;
if (imagestate == ImageLoadState.Ready)
if (imagestate != ImageLoadState.Loading)
{
loadResult.bitmap?.Dispose();
loadResult.bitmap = null;
onlyPreview = true;
}
General.MainWindow.RunOnUIThread(() =>
{
if (imagestate != ImageLoadState.Ready && !onlyPreview)
if (imagestate == ImageLoadState.Loading && !onlyPreview)
{
// Log errors and warnings
foreach (LogMessage message in loadResult.messages)
@ -251,10 +321,13 @@ namespace CodeImp.DoomBuilder.Data
loadfailed = true;
}
bitmap?.Dispose();
loadedbitmap?.Dispose();
texture?.Dispose();
imagestate = ImageLoadState.Ready;
bitmap = loadResult.bitmap;
loadedbitmap = loadResult.bitmap;
alphatest = loadResult.alphatest;
alphatestWidth = loadResult.alphatestWidth;
alphatestHeight = loadResult.alphatestHeight;
if (loadResult.uiThreadWork != null)
loadResult.uiThreadWork();
@ -277,8 +350,12 @@ namespace CodeImp.DoomBuilder.Data
});
// Notify the main thread about the change so that sectors can update their buffers
if (notify) General.MainWindow.ImageDataLoaded(this.name);
}
if (notify)
{
if (this is SpriteImage || this is VoxelImage) General.MainWindow.SpriteDataLoaded(this.Name);
else General.MainWindow.ImageDataLoaded(this.name);
}
}
protected class LocalLoadResult
{
@ -300,6 +377,9 @@ namespace CodeImp.DoomBuilder.Data
public Bitmap bitmap;
public Bitmap preview;
public BitArray alphatest;
public int alphatestWidth;
public int alphatestHeight;
public List<LogMessage> messages;
public Action uiThreadWork;
}
@ -568,6 +648,29 @@ namespace CodeImp.DoomBuilder.Data
loadResult.preview = preview;
}
void MakeAlphaTestImage(LocalLoadResult loadResult)
{
if (loadResult.bitmap == null)
return;
int width = loadResult.bitmap.Width;
int height = loadResult.bitmap.Height;
loadResult.alphatestWidth = width;
loadResult.alphatestHeight = height;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (loadResult.bitmap.GetPixel(x, y).A == 0)
{
if (loadResult.alphatest == null)
loadResult.alphatest = new BitArray(width * height, true);
loadResult.alphatest.Set(x + y * width, false);
}
}
}
}
Texture GetTexture()
{
if (texture != null)
@ -583,13 +686,18 @@ namespace CodeImp.DoomBuilder.Data
return General.Map.Data.LoadingTexture;
}
texture = new Texture(General.Map.Graphics, bitmap);
texture = new Texture(General.Map.Graphics, loadedbitmap);
if (dynamictexture)
{
if ((width != texture.Width) || (height != texture.Height))
throw new Exception("Could not create a texture with the same size as the image.");
}
else
{
loadedbitmap.Dispose();
loadedbitmap = null;
}
#if DEBUG
texture.Tag = name; //mxd. Helps with tracking undisposed resources...
@ -605,7 +713,7 @@ namespace CodeImp.DoomBuilder.Data
if((texture != null) && !texture.Disposed)
{
General.Map.Graphics.SetPixels(texture, bitmap);
General.Map.Graphics.SetPixels(texture, loadedbitmap);
}
}
@ -625,16 +733,21 @@ namespace CodeImp.DoomBuilder.Data
// Make a copy
return new Bitmap(previewbitmap);
}
// Loading failed?
if(loadfailed)
// Loading failed?
if (loadfailed)
{
// Return error bitmap
return Properties.Resources.Failed;
}
// Return loading bitmap
return Properties.Resources.Hourglass;
if (previewstate == ImageLoadState.None)
{
General.Map.Data.QueueLoadPreview(this);
}
// Return loading bitmap
return Properties.Resources.Hourglass;
}
//mxd. This greatly speeds up Dictionary lookups

View file

@ -16,6 +16,7 @@
#region ================== Namespaces
using System.Drawing;
using System.IO;
using CodeImp.DoomBuilder.IO;
@ -39,80 +40,90 @@ namespace CodeImp.DoomBuilder.Data
private static readonly int[] JPG_SIGNATURE = new[] { 255, 216, 255 }; //mxd
private static readonly int[] PCX_SIGNATURE = new[] { 10, 5, 1, 8 }; //mxd
// This check image data and returns the appropriate image reader
public static IImageReader GetImageReader(Stream data, int guessformat, Playpal palette)
{
if(data == null) return new UnknownImageReader(); //mxd
// Try load image data with the appropriate image reader. Returns null if the image could not be loaded
public static Bitmap TryLoadImage(Stream data, int guessformat = UNKNOWN, Playpal palette = null)
{
int offsetx, offsety;
return TryLoadImage(data, guessformat, palette, out offsetx, out offsety);
}
// Data long enough to check for signatures?
if (data.Length > 10)
{
uint ilType = DevilImageType.IL_TYPE_UNKNOWN;
public static Bitmap TryLoadImage(Stream data, int guessformat, Playpal palette, out int offsetx, out int offsety)
{
offsetx = int.MinValue;
offsety = int.MinValue;
try
{
if (data == null) return null;
// Check for PNG signature
if (CheckSignature(data, PNG_SIGNATURE))
ilType = DevilImageType.IL_PNG;
// Check for DDS signature
else if (CheckSignature(data, DDS_SIGNATURE))
ilType = DevilImageType.IL_DDS;
//mxd. Check for PCX signature
else if (CheckSignature(data, PCX_SIGNATURE))
ilType = DevilImageType.IL_PCX;
//mxd. Check for JPG signature
else if (CheckSignature(data, JPG_SIGNATURE))
ilType = DevilImageType.IL_JPG;
//mxd. TGA is VERY special in that it doesn't have a proper signature...
else if (CheckTgaSignature(data))
ilType = DevilImageType.IL_TGA;
//
if (ilType != DevilImageType.IL_TYPE_UNKNOWN)
// Data long enough to check for signatures?
if (data.Length > 10)
{
FileImageReader ilreader = new FileImageReader(ilType, guessformat, palette);
// also fill in the possible proxy type
return ilreader;
IImageReader loader = null;
if (CheckSignature(data, PNG_SIGNATURE))
loader = new FrameworkImageReader(true);
else if (CheckSignature(data, JPG_SIGNATURE))
loader = new FrameworkImageReader(false);
else if (CheckSignature(data, PCX_SIGNATURE))
loader = new PcxImageReader();
else if (CheckTgaSignature(data))
loader = new TgaImageReader();
if (loader != null)
{
data.Seek(0, SeekOrigin.Begin);
try
{
Bitmap image = loader.ReadAsBitmap(data, out offsetx, out offsety);
if (image != null) // The older loaders return null when they should throw an exception
return image;
}
catch
{
}
}
}
/*
// Check for GIF signature
if(CheckSignature(data, GIF_SIGNATURE)) return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom
IImageReader doomloader = null;
// Check for BMP signature
if(CheckSignature(data, BMP_SIGNATURE)) return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom
*/
}
// Could it be a doom picture?
switch(guessformat)
{
case DOOMPICTURE:
// Check if data is valid for a doom picture
data.Seek(0, SeekOrigin.Begin);
DoomPictureReader picreader = new DoomPictureReader(palette);
if(picreader.Validate(data)) return picreader;
break;
// Could it be a doom picture?
switch (guessformat)
{
case DOOMPICTURE:
// Check if data is valid for a doom picture
data.Seek(0, SeekOrigin.Begin);
DoomPictureReader picreader = new DoomPictureReader(palette);
if (picreader.Validate(data)) doomloader = picreader;
break;
case DOOMFLAT:
// Check if data is valid for a doom flat
data.Seek(0, SeekOrigin.Begin);
DoomFlatReader flatreader = new DoomFlatReader(palette);
if(flatreader.Validate(data)) return flatreader;
break;
case DOOMFLAT:
// Check if data is valid for a doom flat
data.Seek(0, SeekOrigin.Begin);
DoomFlatReader flatreader = new DoomFlatReader(palette);
if (flatreader.Validate(data)) doomloader = flatreader;
break;
case DOOMCOLORMAP:
// Check if data is valid for a doom colormap
data.Seek(0, SeekOrigin.Begin);
DoomColormapReader colormapreader = new DoomColormapReader(palette);
if(colormapreader.Validate(data)) return colormapreader;
break;
}
// Format not supported
return new UnknownImageReader();
case DOOMCOLORMAP:
// Check if data is valid for a doom colormap
data.Seek(0, SeekOrigin.Begin);
DoomColormapReader colormapreader = new DoomColormapReader(palette);
if (colormapreader.Validate(data)) doomloader = colormapreader;
break;
}
if (doomloader != null)
{
data.Seek(0, SeekOrigin.Begin);
Bitmap image = doomloader.ReadAsBitmap(data, out offsetx, out offsety);
if (image != null)
return image;
}
return null;
}
catch
{
return null;
}
}
// This checks a signature as byte array

View file

@ -122,21 +122,7 @@ namespace CodeImp.DoomBuilder.Data
if (filedata != null)
{
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette);
if(!(reader is UnknownImageReader))
{
// Load the image
filedata.Seek(0, SeekOrigin.Begin);
try
{
bitmap = reader.ReadAsBitmap(filedata);
}
catch(InvalidDataException)
{
// Data cannot be read!
bitmap = null;
}
}
bitmap = ImageDataFormat.TryLoadImage(filedata, probableformat, General.Map.Data.Palette);
// Not loaded?
if(bitmap == null)

View file

@ -60,9 +60,8 @@ namespace CodeImp.DoomBuilder.Data
bmp.Dispose();
bitmapdata.Dispose();
// We have no destructor
GC.SuppressFinalize(this);
}
LoadImageNow();
}
#endregion
@ -85,7 +84,8 @@ namespace CodeImp.DoomBuilder.Data
//mxd
public override Image GetPreview()
{
return base.GetBitmap();
Stream bitmapdata = assembly.GetManifestResourceStream(resourcename);
return Image.FromStream(bitmapdata);
}
#endregion

View file

@ -79,19 +79,7 @@ namespace CodeImp.DoomBuilder.Data
MemoryStream mem = new MemoryStream(membytes);
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(!(reader is UnknownImageReader))
{
// Load the image
mem.Seek(0, SeekOrigin.Begin);
try { bitmap = reader.ReadAsBitmap(mem); }
catch(InvalidDataException)
{
// Data cannot be read!
bitmap = null;
}
}
bitmap = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
// Not loaded?
if(bitmap == null)

View file

@ -67,16 +67,6 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Methods
//mxd
override public void LoadImage(bool notify)
{
// Do the loading
base.LoadImage(false);
// Notify the main thread about the change to redraw display
if (notify) General.MainWindow.SpriteDataLoaded(this.Name);
}
// This loads the image
protected override LocalLoadResult LocalLoadImage()
{
@ -88,19 +78,11 @@ namespace CodeImp.DoomBuilder.Data
if(lumpdata != null)
{
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(lumpdata, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(reader is UnknownImageReader)
bitmap = ImageDataFormat.TryLoadImage(lumpdata, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette, out offsetx, out offsety);
if(bitmap == null)
{
// Data is in an unknown format!
error = "Sprite lump \"" + Path.Combine(spritelocation, Name) + "\" data format could not be read. Does this lump contain valid picture data at all?";
bitmap = null;
}
else
{
// Read data as bitmap
lumpdata.Seek(0, SeekOrigin.Begin);
if(bitmap != null) bitmap.Dispose();
bitmap = reader.ReadAsBitmap(lumpdata, out offsetx, out offsety);
}
// Done

View file

@ -163,17 +163,16 @@ namespace CodeImp.DoomBuilder.Data
MemoryStream mem = new MemoryStream(membytes);
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(reader is UnknownImageReader)
Bitmap patchbmp = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(patchbmp == null)
{
//mxd. Probably that's a flat?..
if(General.Map.Config.MixTexturesFlats)
{
reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
patchbmp = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
}
if(reader is UnknownImageReader)
if(patchbmp == null)
{
// Data is in an unknown format!
if(!nulltexture) messages.Add(new LogMessage(optional ? ErrorType.Warning : ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\""));
@ -181,29 +180,15 @@ namespace CodeImp.DoomBuilder.Data
}
}
if(!(reader is UnknownImageReader))
if(patchbmp != null)
{
// Get the patch
mem.Seek(0, SeekOrigin.Begin);
Bitmap patchbmp = null;
try { patchbmp = reader.ReadAsBitmap(mem); }
catch(InvalidDataException)
{
// Data cannot be read!
if(!nulltexture) messages.Add(new LogMessage(optional ? ErrorType.Warning : ErrorType.Error, "Patch lump \"" + p.LumpName + "\" data format could not be read, while loading texture \"" + this.Name + "\""));
missingpatches++; //mxd
}
//mxd. Apply transformations from TexturePatch
patchbmp = TransformPatch(bitmap, p, patchbmp);
if(patchbmp != null)
{
//mxd. Apply transformations from TexturePatch
patchbmp = TransformPatch(bitmap, p, patchbmp);
// Draw the patch on the texture image
Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
patchbmp.Dispose();
}
// Draw the patch on the texture image
Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
patchbmp.Dispose();
}
// Done
@ -217,8 +202,6 @@ namespace CodeImp.DoomBuilder.Data
ImageData img = General.Map.Data.GetTextureImage(p.LumpName);
if(!(img is UnknownImage) && img != this)
{
if(!img.IsImageLoaded) img.LoadImage();
//mxd. Apply transformations from TexturePatch. We don't want to modify the original bitmap here, so make a copy
Bitmap bmp = new Bitmap(img.LocalGetBitmap());
Bitmap patchbmp = TransformPatch(bitmap, p, bmp);

View file

@ -109,15 +109,15 @@ namespace CodeImp.DoomBuilder.Data
if(patchdata != null)
{
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(patchdata, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(reader is UnknownImageReader)
Bitmap patchbmp = ImageDataFormat.TryLoadImage(patchdata, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(patchbmp == null)
{
//mxd. Probably that's a flat?..
if(General.Map.Config.MixTexturesFlats)
{
reader = ImageDataFormat.GetImageReader(patchdata, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
patchbmp = ImageDataFormat.TryLoadImage(patchdata, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
}
if(reader is UnknownImageReader)
if(patchbmp == null)
{
// Data is in an unknown format!
messages.Add(new LogMessage(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?"));
@ -125,17 +125,11 @@ namespace CodeImp.DoomBuilder.Data
}
}
if(!(reader is UnknownImageReader))
if(patchbmp != null)
{
// Draw the patch
patchdata.Seek(0, SeekOrigin.Begin);
try { reader.DrawToPixelData(patchdata, pixels, width, height, p.X, p.Y); }
catch(InvalidDataException)
{
// Data cannot be read!
messages.Add(new LogMessage(ErrorType.Error, "Patch lump \"" + p.LumpName + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?"));
missingpatches++; //mxd
}
DrawToPixelData(patchbmp, pixels, width, height, p.X, p.Y);
patchbmp.Dispose();
}
// Done
@ -163,6 +157,38 @@ namespace CodeImp.DoomBuilder.Data
return new LocalLoadResult(bitmap, messages);
}
#endregion
}
// This draws the picture to the given pixel color data
static unsafe void DrawToPixelData(Bitmap bmp, PixelColor* target, int targetwidth, int targetheight, int x, int y)
{
// Get bitmap
int width = bmp.Size.Width;
int height = bmp.Size.Height;
// Lock bitmap pixels
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
PixelColor* pixels = (PixelColor*)bmpdata.Scan0.ToPointer();
// Go for all pixels in the original image
for (int ox = 0; ox < width; ox++)
{
for (int oy = 0; oy < height; oy++)
{
// Copy this pixel?
if (pixels[oy * width + ox].a > 0.5f)
{
// Calculate target pixel and copy when within bounds
int tx = x + ox;
int ty = y + oy;
if ((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
target[ty * targetwidth + tx] = pixels[oy * width + ox];
}
}
}
// Done
bmp.UnlockBits(bmpdata);
}
#endregion
}
}

View file

@ -34,18 +34,15 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Constructor / Disposer
// Constructor
public UnknownImage(Bitmap image)
public UnknownImage()
{
// Initialize
this.width = 0;
this.height = 0;
this.loadbitmap = image;
this.loadbitmap = Properties.Resources.UnknownImage;
SetName("");
LoadImage(false);
// We have no destructor
GC.SuppressFinalize(this);
LoadImageNow();
}
#endregion
@ -55,7 +52,7 @@ namespace CodeImp.DoomBuilder.Data
// This 'loads' the image
protected override LocalLoadResult LocalLoadImage()
{
return new LocalLoadResult(loadbitmap);
return new LocalLoadResult(new Bitmap(loadbitmap));
}
// This returns a preview image

View file

@ -53,15 +53,6 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Methods
override public void LoadImage(bool notify)
{
// Do the loading
base.LoadImage(false);
// Notify the main thread about the change to redraw display
if (notify) General.MainWindow.SpriteDataLoaded(this.Name);
}
// This loads the image
protected unsafe override LocalLoadResult LocalLoadImage()
{

View file

@ -55,7 +55,7 @@ namespace CodeImp.DoomBuilder.Editing
// Background
private string background = "";
private int backsource;
private ImageData backimage = new UnknownImage(null);
private ImageData backimage = new UnknownImage();
private int backoffsetx, backoffsety;
private float backscalex, backscaley;
@ -234,7 +234,7 @@ namespace CodeImp.DoomBuilder.Editing
}
// Make sure it is loaded
backimage.LoadImage();
backimage.LoadImageNow();
}
// This returns the next higher coordinate

View file

@ -277,9 +277,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
if (General.Map.Data.GetTextureExists(name))
{
ImageData image = General.Map.Data.GetTextureImage(name);
if (!image.IsImageLoaded)
image.LoadImage();
image.LoadImageNow();
t = image.Texture;
@ -296,9 +294,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
if (General.Map.Data.GetTextureExists(name))
{
ImageData image = General.Map.Data.GetTextureImage(name);
if (!image.IsImageLoaded)
image.LoadImage();
image.LoadImageNow();
t = image.Texture;
}
@ -312,9 +308,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
if (General.Map.Data.GetSpriteExists(name))
{
ImageData image = General.Map.Data.GetSpriteImage(name);
if (!image.IsImageLoaded)
image.LoadImage();
image.LoadImageNow();
t = image.Texture;
}
@ -1642,11 +1636,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
Texture texture = null;
//create texture
FileImageReader fir = new FileImageReader();
Bitmap bitmap = fir.ReadAsBitmap(ms);
ms.Close();
//create texture
Bitmap bitmap = ImageDataFormat.TryLoadImage(ms);
if(bitmap != null)
{
texture = new Texture(General.Map.Graphics, bitmap);

View file

@ -49,11 +49,6 @@ namespace CodeImp.DoomBuilder
{
#region ================== API Declarations
#if !NO_DEVIL
[DllImport("devil.dll")]
private static extern void ilInit();
#endif
#if NO_WIN32
internal static bool LockWindowUpdate(IntPtr hwnd) { return true; }
@ -634,10 +629,6 @@ namespace CodeImp.DoomBuilder
// Initialize static classes
MapSet.Initialize();
#if !NO_DEVIL
ilInit();
#endif
// Create main window
General.WriteLogLine("Loading main interface window...");
mainwindow = new MainForm();

View file

@ -73,22 +73,21 @@ namespace CodeImp.DoomBuilder.Geometry
// This calculates the area
public float CalculateArea()
{
// Multiply the x coordinate of each vertex by the y coordinate of the next vertex.
// Multiply the y coordinate of each vertex by the x coordinate of the next vertex.
// Subtract these.
float result = 0.0f;
int firstcalculated = 0;
LinkedListNode<EarClipVertex> n1 = base.First;
while(firstcalculated < 2)
{
LinkedListNode<EarClipVertex> n2 = n1.Next ?? base.First;
float a = n1.Value.Position.x * n2.Value.Position.y;
float b = n1.Value.Position.y * n2.Value.Position.x;
result += a - b;
n1 = n2;
if(n2 == base.First) firstcalculated++;
}
return Math.Abs(result / 2.0f);
float area = 0;
LinkedListNode<EarClipVertex> v = First;
do
{
EarClipVertex v1 = v.Value;
EarClipVertex v2 = (v.Next != null) ? v.Next.Value : First.Value;
area += (v2.Position.x + v1.Position.x) * (v2.Position.y - v1.Position.y);
v = v.Next;
}
while (v != null);
return Math.Abs(area * 0.5f);
}
// This creates a bounding box from the outer polygon

View file

@ -69,17 +69,11 @@ namespace CodeImp.DoomBuilder.IO
// This creates a Bitmap from the given data
// Returns null on failure
public Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
public unsafe Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
{
offsetx = int.MinValue;
offsety = int.MinValue;
return ReadAsBitmap(stream);
}
// This creates a Bitmap from the given data
// Returns null on failure
public unsafe Bitmap ReadAsBitmap(Stream stream)
{
int width, height;
// Read pixel data
@ -116,41 +110,6 @@ namespace CodeImp.DoomBuilder.IO
}
}
// This draws the picture to the given pixel color data
// Throws exception on failure
public unsafe void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
{
// Get bitmap
Bitmap bmp = ReadAsBitmap(stream);
int width = bmp.Size.Width;
int height = bmp.Size.Height;
// Lock bitmap pixels
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
PixelColor* pixels = (PixelColor*)bmpdata.Scan0.ToPointer();
// Go for all pixels in the original image
for(int ox = 0; ox < width; ox++)
{
for(int oy = 0; oy < height; oy++)
{
// Copy this pixel?
if(pixels[oy * width + ox].a > 0.5f)
{
// Calculate target pixel and copy when within bounds
int tx = x + ox;
int ty = y + oy;
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
target[ty * targetwidth + tx] = pixels[oy * width + ox];
}
}
}
// Done
bmp.UnlockBits(bmpdata);
bmp.Dispose();
}
// This creates pixel color data from the given data
// Returns null on failure
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height)

View file

@ -72,13 +72,7 @@ namespace CodeImp.DoomBuilder.IO
{
offsetx = int.MinValue;
offsety = int.MinValue;
return ReadAsBitmap(stream);
}
// This creates a Bitmap from the given data
// Returns null on failure
public Bitmap ReadAsBitmap(Stream stream)
{
int width, height;
Bitmap bmp;
@ -118,41 +112,6 @@ namespace CodeImp.DoomBuilder.IO
return bmp;
}
// This draws the picture to the given pixel color data
// Throws exception on failure
public void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
{
// Get bitmap
Bitmap bmp = ReadAsBitmap(stream);
int width = bmp.Size.Width;
int height = bmp.Size.Height;
// Lock bitmap pixels
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
PixelColor* pixels = (PixelColor*)bmpdata.Scan0.ToPointer();
// Go for all pixels in the original image
for(int ox = 0; ox < width; ox++)
{
for(int oy = 0; oy < height; oy++)
{
// Copy this pixel?
if(pixels[oy * width + ox].a > 0.5f)
{
// Calculate target pixel and copy when within bounds
int tx = x + ox;
int ty = y + oy;
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
target[ty * targetwidth + tx] = pixels[oy * width + ox];
}
}
}
// Done
bmp.UnlockBits(bmpdata);
bmp.Dispose();
}
// This creates pixel color data from the given data
// Returns null on failure
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height)

View file

@ -86,14 +86,6 @@ namespace CodeImp.DoomBuilder.IO
return true;
}
// This creates a Bitmap from the given data
// Returns null on failure
public Bitmap ReadAsBitmap(Stream stream)
{
int x, y;
return ReadAsBitmap(stream, out x, out y);
}
// This creates a Bitmap from the given data
// Returns null on failure
public Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
@ -137,40 +129,6 @@ namespace CodeImp.DoomBuilder.IO
return bmp;
}
// This draws the picture to the given pixel color data
// Throws exception on failure
public void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
{
int width, height, ox, oy;
// Read pixel data
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
if(pixeldata != null)
{
// Go for all source pixels
// We don't care about the original image offset, so reuse ox/oy
for(ox = 0; ox < width; ox++)
{
for(oy = 0; oy < height; oy++)
{
// Copy this pixel?
if(pixeldata[oy * width + ox].a > 0.5f)
{
// Calculate target pixel and copy when within bounds
int tx = x + ox;
int ty = y + oy;
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
target[ty * targetwidth + tx] = pixeldata[oy * width + ox];
}
}
}
}
else
{
throw new InvalidDataException("Failed to read pixeldata"); //mxd. Let's throw exception on failure
}
}
// This creates pixel color data from the given data
// Returns null on failure
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety)

File diff suppressed because it is too large Load diff

View file

@ -26,9 +26,6 @@ namespace CodeImp.DoomBuilder.IO
{
internal unsafe interface IImageReader
{
// Methods
Bitmap ReadAsBitmap(Stream stream);
Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety);
void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y);
}
}

View file

@ -1,102 +0,0 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* 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.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.IO;
using System.Drawing;
using CodeImp.DoomBuilder.Rendering;
using System.Drawing.Imaging;
#endregion
namespace CodeImp.DoomBuilder.IO
{
internal class UnknownImageReader : IImageReader
{
#region ================== Constructor / Disposer
// Constructor
public UnknownImageReader()
{
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
// This creates a Bitmap from the given data
// Returns null on failure
public Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
{
offsetx = int.MinValue;
offsety = int.MinValue;
return ReadAsBitmap(stream);
}
// This reads the image and returns a Bitmap
public Bitmap ReadAsBitmap(Stream stream)
{
return new Bitmap(Properties.Resources.Failed);
}
// This reads the image and returns a Bitmap
/*public static Bitmap ReadAsBitmap() //mxd. Never used
{
return new Bitmap(Properties.Resources.Failed);
}*/
// This draws the picture to the given pixel color data
// Throws exception on failure
public unsafe void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
{
// Get bitmap
Bitmap bmp = ReadAsBitmap(stream);
int width = bmp.Size.Width;
int height = bmp.Size.Height;
// Lock bitmap pixels
BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
PixelColor* pixels = (PixelColor*)bmpdata.Scan0.ToPointer();
// Go for all pixels in the original image
for(int ox = 0; ox < width; ox++)
{
for(int oy = 0; oy < height; oy++)
{
// Copy this pixel?
if(pixels[oy * width + ox].a > 0.5f)
{
// Calculate target pixel and copy when within bounds
int tx = x + ox;
int ty = y + oy;
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
target[ty * targetwidth + tx] = pixels[oy * width + ox];
}
}
}
// Done
bmp.UnlockBits(bmpdata);
bmp.Dispose();
}
#endregion
}
}

View file

@ -59,7 +59,7 @@ namespace CodeImp.DoomBuilder.Rendering
public Plotter(int width, int height)
{
// Initialize
Texture = new Texture(width, height);
Texture = new Texture(width, height, TextureFormat.Bgra8);
this.pixels = new PixelColor[width*height];
this.width = width;
this.height = height;

View file

@ -96,6 +96,7 @@ namespace CodeImp.DoomBuilder.Rendering
// fog 3d shaders
CompileShader(ShaderName.world3d_main_fog, "world3d.shader", "world3d_main_fog");
CompileShader(ShaderName.world3d_main_highlight_vertexcolor, "world3d.shader", "world3d_highlight_vertexcolor");
CompileShader(ShaderName.world3d_main_highlight_fog, "world3d.shader", "world3d_main_highlight_fog");
CompileShader(ShaderName.world3d_main_fog_vertexcolor, "world3d.shader", "world3d_main_fog_vertexcolor");
CompileShader(ShaderName.world3d_main_highlight_fog_vertexcolor, "world3d.shader", "world3d_main_highlight_fog_vertexcolor");

View file

@ -356,9 +356,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Create rendertargets textures
plotter = new Plotter(windowsize.Width, windowsize.Height);
gridplotter = new Plotter(windowsize.Width, windowsize.Height);
thingstex = new Texture(windowsize.Width, windowsize.Height);
overlaytex = new Texture(windowsize.Width, windowsize.Height);
surfacetex = new Texture(windowsize.Width, windowsize.Height);
thingstex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
overlaytex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
surfacetex = new Texture(windowsize.Width, windowsize.Height, TextureFormat.Rgba8);
// Clear rendertargets
graphics.ClearTexture(General.Colors.Background.WithAlpha(0).ToColorValue(), thingstex);

View file

@ -780,13 +780,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Render the geometry collected
foreach (KeyValuePair<ImageData, List<VisualGeometry>> group in geopass)
{
// What texture to use?
if(group.Key is UnknownImage)
curtexture = General.Map.Data.UnknownTexture3D;
else if(group.Key.IsImageLoaded && !group.Key.IsDisposed)
curtexture = group.Key;
else
curtexture = General.Map.Data.Hourglass3D;
curtexture = group.Key;
// Apply texture
graphics.SetTexture(curtexture.Texture);
@ -927,11 +921,7 @@ namespace CodeImp.DoomBuilder.Rendering
{
if(group.Key is UnknownImage) continue;
// What texture to use?
if(!group.Key.IsImageLoaded || group.Key.IsDisposed)
curtexture = General.Map.Data.Hourglass3D;
else
curtexture = group.Key;
curtexture = group.Key;
// Apply texture
graphics.SetTexture(curtexture.Texture);
@ -1155,13 +1145,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Change texture?
if(g.Texture.LongName != curtexturename)
{
// What texture to use?
if(g.Texture is UnknownImage)
curtexture = General.Map.Data.UnknownTexture3D;
else if(g.Texture.IsImageLoaded && !g.Texture.IsDisposed)
curtexture = g.Texture;
else
curtexture = General.Map.Data.Hourglass3D;
curtexture = g.Texture;
// Apply texture
graphics.SetTexture(curtexture.Texture);
@ -1288,11 +1272,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Change texture?
if(t.Texture.LongName != curtexturename)
{
// What texture to use?
if(t.Texture.IsImageLoaded && !t.Texture.IsDisposed)
curtexture = t.Texture;
else
curtexture = General.Map.Data.Hourglass3D;
curtexture = t.Texture;
// Apply texture
graphics.SetTexture(curtexture.Texture);

View file

@ -7,6 +7,20 @@ 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()
@ -41,26 +55,28 @@ namespace CodeImp.DoomBuilder.Rendering
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);
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);
protected static extern void Texture_SetCubeImage(IntPtr handle, int size, TextureFormat format);
}
public class Texture : BaseTexture
{
public Texture(int width, int height)
public Texture(int width, int height, TextureFormat format)
{
Width = width;
Height = height;
Texture_Set2DImage(Handle, Width, Height);
Format = format;
Texture_Set2DImage(Handle, Width, Height, Format);
}
public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height);
Format = TextureFormat.Bgra8;
Texture_Set2DImage(Handle, Width, Height, Format);
device.SetPixels(this, bitmap);
}
@ -70,13 +86,15 @@ namespace CodeImp.DoomBuilder.Rendering
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, 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; }
}
@ -85,7 +103,7 @@ namespace CodeImp.DoomBuilder.Rendering
{
public CubeTexture(RenderDevice device, int size)
{
Texture_SetCubeImage(Handle, size);
Texture_SetCubeImage(Handle, size, TextureFormat.Bgra8);
}
}

View file

@ -311,7 +311,7 @@ shader world3d_main_highlight_fog extends world3d_main_fog
{
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);
tcolor = vec4(getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal).rgb, tcolor.a);
if (tcolor.a == 0.0)
{
out.FragColor = tcolor;

View file

@ -110,7 +110,6 @@ namespace CodeImp.DoomBuilder.Windows
"Deal with it",
"Error 47",
"YOU DIED",
"Thanks, Obama",
"The God Of Exceptions Demands MORE Exceptions!",
"Good. It's boring here anyway.",
"Shameful display!",

View file

@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.Windows
showbackground.Checked = true;
backgroundname = General.Map.Grid.BackgroundName;
backgroundsource = General.Map.Grid.BackgroundSource;
General.DisplayZoomedImage(backgroundimage, General.Map.Grid.Background.GetBitmap());
General.DisplayZoomedImage(backgroundimage, General.Map.Grid.Background.GetBackgroundBitmap());
}
else
{
@ -93,8 +93,7 @@ namespace CodeImp.DoomBuilder.Windows
backgroundname = result;
backgroundsource = GridSetup.SOURCE_TEXTURES;
ImageData img = General.Map.Data.GetTextureImage(result);
img.LoadImage();
General.DisplayZoomedImage(backgroundimage, img.GetBitmap());
General.DisplayZoomedImage(backgroundimage, img.GetBackgroundBitmap());
}
}
@ -109,8 +108,7 @@ namespace CodeImp.DoomBuilder.Windows
backgroundname = result;
backgroundsource = GridSetup.SOURCE_FLATS;
ImageData img = General.Map.Data.GetFlatImage(result);
img.LoadImage();
General.DisplayZoomedImage(backgroundimage, img.GetBitmap());
General.DisplayZoomedImage(backgroundimage, img.GetBackgroundBitmap());
}
}
@ -124,8 +122,7 @@ namespace CodeImp.DoomBuilder.Windows
backgroundname = browsefile.FileName;
backgroundsource = GridSetup.SOURCE_FILE;
ImageData img = new FileImage(Path.GetFileNameWithoutExtension(backgroundname), backgroundname, false, 1.0f, 1.0f);
img.LoadImage();
General.DisplayZoomedImage(backgroundimage, new Bitmap(img.GetBitmap()));
General.DisplayZoomedImage(backgroundimage, new Bitmap(img.GetBackgroundBitmap()));
img.Dispose();
}
}

View file

@ -4214,14 +4214,6 @@ namespace CodeImp.DoomBuilder.Windows
});
}
public void ResourcesLoaded(string loadtime)
{
RunOnUIThread(() =>
{
DisplayStatus(StatusType.Info, "Resources loaded in " + loadtime + " seconds");
});
}
#endregion
#region ================== Message Pump
@ -4377,10 +4369,6 @@ namespace CodeImp.DoomBuilder.Windows
//mxd
internal void ResetClock()
{
// Let the data manager know...
if(General.Map != null && General.Map.Data != null)
General.Map.Data.OnBeforeClockReset();
Clock.Reset();
lastupdatetime = 0;

View file

@ -34,7 +34,13 @@ namespace CodeImp.DoomBuilder.ZDoom
public const string FLICKER2 = "flickerlight2";
public const string SECTOR = "sectorlight";
public static readonly Dictionary<string, GZGeneral.LightModifier> GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary<string, GZGeneral.LightModifier>(StringComparer.Ordinal) { { POINT, GZGeneral.LightModifier.NORMAL }, { PULSE, GZGeneral.LightModifier.PULSE }, { FLICKER, GZGeneral.LightModifier.FLICKER }, { FLICKER2, GZGeneral.LightModifier.FLICKERRANDOM }, { SECTOR, GZGeneral.LightModifier.SECTOR } };
public static readonly Dictionary<string, GZGeneral.LightModifier> GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary<string, GZGeneral.LightModifier>(StringComparer.OrdinalIgnoreCase) {
{ POINT, GZGeneral.LightModifier.NORMAL },
{ PULSE, GZGeneral.LightModifier.PULSE },
{ FLICKER, GZGeneral.LightModifier.FLICKER },
{ FLICKER2, GZGeneral.LightModifier.FLICKERRANDOM },
{ SECTOR, GZGeneral.LightModifier.SECTOR }
};
}
#endregion
@ -158,7 +164,7 @@ namespace CodeImp.DoomBuilder.ZDoom
private bool ParseLight(string lighttype)
{
DynamicLightData light = new DynamicLightData(new GZGeneral.LightData(GldefsLightType.GLDEFS_TO_GZDOOM_LIGHT_TYPE[lighttype]));
DynamicLightData light = new DynamicLightData(new GZGeneral.LightData(GldefsLightType.GLDEFS_TO_GZDOOM_LIGHT_TYPE[lighttype], GZGeneral.LightRenderStyle.NORMAL));
// Find classname
SkipWhitespace(true);

View file

@ -81,6 +81,13 @@ namespace CodeImp.DoomBuilder.ZDoom
if (_pstruct.ParentName != null)
{
string _pname = _pstruct.ParentName.ToLowerInvariant();
if(_pname == _pstruct.ClassName.ToLowerInvariant())
{
Parser.ReportError("Class \"" + _pstruct.ClassName + "\" is trying to inherit from itself. Class is being skipped.");
return false;
}
Parser.allclasses.TryGetValue(_pname, out _pstruct);
}
else _pstruct = null;

View file

@ -287,13 +287,13 @@ extern "C"
return Backend::Get()->DeleteTexture(tex);
}
void Texture_Set2DImage(Texture* tex, int width, int height)
void Texture_Set2DImage(Texture* tex, int width, int height, PixelFormat format)
{
tex->Set2DImage(width, height);
tex->Set2DImage(width, height, format);
}
void Texture_SetCubeImage(Texture* tex, int size)
void Texture_SetCubeImage(Texture* tex, int size, PixelFormat format)
{
tex->SetCubeImage(size);
tex->SetCubeImage(size, format);
}
}

View file

@ -39,6 +39,22 @@ enum class TextureFilter : int { Nearest, Linear };
enum class MipmapFilter : int { None, Nearest, Linear };
enum class UniformType : int { Vec4f, Vec3f, Vec2f, Float, Mat4, Vec4i, Vec3i, Vec2i, Int, Vec4fArray, Vec3fArray, Vec2fArray };
enum class PixelFormat : int
{
Rgba8,
Bgra8,
Rg16f,
Rgba16f,
R32f,
Rg32f,
Rgb32f,
Rgba32f,
D32f_S8,
D24_S8,
A2Bgr10,
A2Rgb10_snorm
};
typedef int UniformName;
typedef int ShaderName;
@ -106,8 +122,8 @@ class Texture
{
public:
virtual ~Texture() = default;
virtual void Set2DImage(int width, int height) = 0;
virtual void SetCubeImage(int size) = 0;
virtual void Set2DImage(int width, int height, PixelFormat format) = 0;
virtual void SetCubeImage(int size, PixelFormat format) = 0;
};
class Backend

View file

@ -39,20 +39,23 @@ void GLTexture::Finalize()
Invalidate();
}
void GLTexture::Set2DImage(int width, int height)
void GLTexture::Set2DImage(int width, int height, PixelFormat format)
{
if (width < 1) width = 1;
if (height < 1) height = 1;
// This really shouldn't be here. The calling code should send valid input and this should throw an error.
if (width < 1) width = 16;
if (height < 1) height = 16;
mCubeTexture = false;
mWidth = width;
mHeight = height;
mFormat = format;
}
void GLTexture::SetCubeImage(int size)
void GLTexture::SetCubeImage(int size, PixelFormat format)
{
mCubeTexture = true;
mWidth = size;
mHeight = size;
mFormat = format;
}
bool GLTexture::SetPixels(GLRenderDevice* device, const void* data)
@ -70,7 +73,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, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexImage2D(GL_TEXTURE_2D, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), data);
if (data != nullptr)
glGenerateMipmap(GL_TEXTURE_2D);
@ -103,7 +106,7 @@ bool GLTexture::SetCubePixels(GLRenderDevice* device, CubeMapFace face, const vo
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
glTexImage2D(cubeMapFaceToGL[(int)face], 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexImage2D(cubeMapFaceToGL[(int)face], 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), data);
if (data != nullptr && face == CubeMapFace::NegativeZ)
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
@ -152,7 +155,7 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glBindTexture(GL_TEXTURE_2D, oldBinding);
}
@ -163,12 +166,12 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ToInternalFormat(mFormat), mWidth, mHeight, 0, ToDataFormat(mFormat), ToDataType(mFormat), nullptr);
glBindTexture(GL_TEXTURE_CUBE_MAP, oldBinding);
}
@ -241,3 +244,57 @@ GLuint GLTexture::GetPBO(GLRenderDevice* device)
return mPBO;
}
GLint GLTexture::ToInternalFormat(PixelFormat format)
{
static GLint cvt[] =
{
GL_RGBA8,
GL_RGBA8,
GL_RG16F,
GL_RGBA16F,
GL_R32F,
GL_RG32F,
GL_RGB32F,
GL_RGBA32F,
GL_DEPTH32F_STENCIL8,
GL_DEPTH24_STENCIL8
};
return cvt[(int)format];
}
GLenum GLTexture::ToDataFormat(PixelFormat format)
{
static GLint cvt[] =
{
GL_RGBA,
GL_BGRA,
GL_RG,
GL_RGBA,
GL_RED,
GL_RG,
GL_RGB,
GL_RGBA,
GL_DEPTH_STENCIL,
GL_DEPTH_STENCIL
};
return cvt[(int)format];
}
GLenum GLTexture::ToDataType(PixelFormat format)
{
static GLint cvt[] =
{
GL_UNSIGNED_BYTE,
GL_UNSIGNED_BYTE,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT,
GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
GL_UNSIGNED_INT_24_8
};
return cvt[(int)format];
}

View file

@ -34,8 +34,8 @@ public:
void Finalize();
void Set2DImage(int width, int height) override;
void SetCubeImage(int size) override;
void Set2DImage(int width, int height, PixelFormat format) override;
void SetCubeImage(int size, PixelFormat format) override;
bool SetPixels(GLRenderDevice* device, const void* data);
bool SetCubePixels(GLRenderDevice* device, CubeMapFace face, const void* data);
@ -55,8 +55,13 @@ public:
std::list<GLTexture*>::iterator ItTexture;
private:
static GLint ToInternalFormat(PixelFormat format);
static GLenum ToDataFormat(PixelFormat format);
static GLenum ToDataType(PixelFormat format);
int mWidth = 0;
int mHeight = 0;
PixelFormat mFormat = {};
bool mCubeTexture = false;
bool mPBOTexture = false;
GLuint mTexture = 0;

View file

@ -464,6 +464,7 @@ public:
void MakeCurrent() override;
void ClearCurrent() override;
void SwapBuffers() override;
bool IsCurrent() override;
int GetWidth() const override;
int GetHeight() const override;
@ -558,6 +559,11 @@ void OpenGLContext::MakeCurrent()
glx.glXMakeCurrent(disp, window, opengl_context);
}
bool OpenGLContext::IsCurrent()
{
return (glx.glXGetCurrentContext() == opengl_context);
}
void OpenGLContext::ClearCurrent()
{
glx.glXMakeCurrent(0, 0, opengl_context);

View file

@ -131,6 +131,11 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
alphaArgument.SetValue(ctrl.threeDFloor.Alpha);
sectorBrightness.Text = ctrl.threeDFloor.Brightness.ToString();
threeDFloor.FloorSlope = ctrl.ThreeDFloor.FloorSlope;
threeDFloor.FloorSlopeOffset = ctrl.ThreeDFloor.FloorSlopeOffset;
threeDFloor.CeilingSlope = ctrl.ThreeDFloor.CeilingSlope;
threeDFloor.CeilingSlopeOffset = ctrl.ThreeDFloor.CeilingSlopeOffset;
for (int i = 0; i < checkedListBoxSectors.Items.Count; i++)
checkedListBoxSectors.SetItemChecked(i, ctrl.checkedListBoxSectors.GetItemChecked(i));
}

View file

@ -42,6 +42,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
private string bordertexture;
private string topflat;
private string bottomflat;
private Vector3D floorslope;
private float floorslopeoffset;
private Vector3D ceilingslope;
private float ceilingslopeoffset;
private int type;
private int flags;
private int alpha;
@ -72,6 +76,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
public bool Rebuild { get { return rebuild; } set { rebuild = value; } }
public int UDMFTag { get { return udmftag; } set { udmftag = value; } }
public List<int> Tags { get { return tags; } set { tags = value; } }
public Vector3D FloorSlope { get { return floorslope; } set { floorslope = value; } }
public float FloorSlopeOffset { get { return floorslopeoffset; } set { floorslopeoffset = value; } }
public Vector3D CeilingSlope { get { return ceilingslope; } set { ceilingslope = value; } }
public float CeilingSlopeOffset { get { return ceilingslopeoffset; } set { ceilingslopeoffset = value; } }
public ThreeDFloor()
{
@ -85,7 +93,11 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
type = 1;
flags = 0;
tags = new List<int>();
floorslope = new Vector3D(0.0f, 0.0f, 0.0f);
floorslopeoffset = 0.0f;
ceilingslope = new Vector3D(0.0f, 0.0f, 0.0f);
ceilingslopeoffset = 0.0f;
alpha = 255;
}
@ -102,6 +114,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
bottomheight = sector.FloorHeight;
brightness = sector.Brightness;
tags = new List<int>();
floorslope = sector.FloorSlope;
floorslopeoffset = sector.FloorSlopeOffset;
ceilingslope = sector.CeilSlope;
ceilingslopeoffset = sector.CeilSlopeOffset;
foreach (Sidedef sd in sector.Sidedefs)
{
@ -183,6 +199,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
sector.SetFloorTexture(bottomflat);
sector.Brightness = brightness;
sector.Tags = tags;
sector.FloorSlope = floorslope;
sector.FloorSlopeOffset = floorslopeoffset;
sector.CeilSlope = ceilingslope;
sector.CeilSlopeOffset = ceilingslopeoffset;
foreach (Sidedef sd in sector.Sidedefs)
{
@ -219,6 +239,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
sector.CeilHeight = topheight;
sector.SetFloorTexture(bottomflat);
sector.SetCeilTexture(topflat);
sector.FloorSlope = floorslope;
sector.FloorSlopeOffset = floorslopeoffset;
sector.CeilSlope = ceilingslope;
sector.CeilSlopeOffset = ceilingslopeoffset;
foreach (Sidedef sd in sector.Sidedefs)
{

View file

@ -0,0 +1,259 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{88CFD996-027B-4CBE-9828-26B2728B6127}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ThreeDFloorMode</RootNamespace>
<AssemblyName>ThreeDFloorMode</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BuilderPlug.cs" />
<Compile Include="ControlSectorArea.cs" />
<Compile Include="Controls\ThreeDFloorTooltipControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Controls\ThreeDFloorTooltipControl.Designer.cs">
<DependentUpon>ThreeDFloorTooltipControl.cs</DependentUpon>
</Compile>
<Compile Include="DrawSlopesMode.cs" />
<Compile Include="Interface\PreferencesForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Interface\PreferencesForm.Designer.cs">
<DependentUpon>PreferencesForm.cs</DependentUpon>
</Compile>
<Compile Include="Interface\ThreeDFloorPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Interface\ThreeDFloorPanel.Designer.cs">
<DependentUpon>ThreeDFloorPanel.cs</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Controls\ThreeDFloorControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Controls\ThreeDFloorControl.Designer.cs">
<DependentUpon>ThreeDFloorControl.cs</DependentUpon>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="SectorLabelInfo.cs" />
<Compile Include="SlopeMode.cs" />
<Compile Include="SlopeVertex.cs" />
<Compile Include="SlopeVertexGroup.cs" />
<Compile Include="ThreeDFloor.cs" />
<Compile Include="ThreeDFloorMode.cs" />
<Compile Include="Windows\ControlSectorAreaConfig.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\ControlSectorAreaConfig.Designer.cs">
<DependentUpon>ControlSectorAreaConfig.cs</DependentUpon>
</Compile>
<Compile Include="Windows\MenusForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\MenusForm.Designer.cs">
<DependentUpon>MenusForm.cs</DependentUpon>
</Compile>
<Compile Include="Windows\SlopeDataSectorDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\SlopeDataSectorDialog.Designer.cs">
<DependentUpon>SlopeDataSectorDialog.cs</DependentUpon>
</Compile>
<Compile Include="Windows\SlopeVertexEditForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\SlopeVertexEditForm.Designer.cs">
<DependentUpon>SlopeVertexEditForm.cs</DependentUpon>
</Compile>
<Compile Include="Windows\ThreeDFloorEditorWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\ThreeDFloorEditorWindow.Designer.cs">
<DependentUpon>ThreeDFloorEditorWindow.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Controls\ThreeDFloorControl.resx">
<DependentUpon>ThreeDFloorControl.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Interface\PreferencesForm.resx">
<DependentUpon>PreferencesForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Resources\Actions.cfg" />
<EmbeddedResource Include="Windows\ThreeDFloorEditorWindow.resx">
<DependentUpon>ThreeDFloorEditorWindow.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Controls\ThreeDFloorTooltipControl.resx">
<DependentUpon>ThreeDFloorTooltipControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Interface\ThreeDFloorPanel.resx">
<DependentUpon>ThreeDFloorPanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Resources\ThreeDFloorIcon.png" />
<EmbeddedResource Include="Windows\ControlSectorAreaConfig.resx">
<DependentUpon>ControlSectorAreaConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\SlopeVertexEditForm.resx">
<DependentUpon>SlopeVertexEditForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\SlopeModeIcon.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\DrawSlopeModeIcon.png" />
<EmbeddedResource Include="Windows\MenusForm.resx">
<DependentUpon>MenusForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Resources\Ceiling.png" />
<EmbeddedResource Include="Resources\Floor.png" />
<EmbeddedResource Include="Resources\FloorAndCeiling.png" />
<EmbeddedResource Include="Windows\SlopeDataSectorDialog.resx">
<DependentUpon>SlopeDataSectorDialog.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\BuilderMono.csproj">
<Project>{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}</Project>
<Name>Builder</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\BuilderEffects\BuilderEffectsMono.csproj">
<Project>{B859BE0F-A992-476D-A642-FA8EFE94AAA5}</Project>
<Name>BuilderEffects</Name>
</ProjectReference>
<ProjectReference Include="..\BuilderModes\BuilderModesMono.csproj">
<Project>{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}</Project>
<Name>BuilderModes</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1550,19 +1550,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update floor slope?
if(s.FloorSlope.GetLengthSq() > 0 && !float.IsNaN(s.FloorSlopeOffset / s.FloorSlope.z))
{
Plane floor = new Plane(s.FloorSlope, s.FloorSlopeOffset);
Vector2D center = new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2);
s.FloorSlope = new Vector3D(new Vector2D(s.FloorSlope.x, s.FloorSlope.y).GetRotated(rotation), s.FloorSlope.z);
s.FloorSlopeOffset = -Vector3D.DotProduct(s.FloorSlope, new Vector3D(center + relativeoffset, floor.GetZ(center)));
Vector3D center = new Vector3D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2, s.FloorHeight);
Plane p = new Plane(center, s.FloorSlope.GetAngleXY() + rotation + Angle2D.PIHALF, -s.FloorSlope.GetAngleZ(), true);
s.FloorSlope = p.Normal;
s.FloorSlopeOffset = p.Offset;
}
// Update ceiling slope?
if(s.CeilSlope.GetLengthSq() > 0 && !float.IsNaN(s.CeilSlopeOffset / s.CeilSlope.z))
{
Plane ceiling = new Plane(s.CeilSlope, s.CeilSlopeOffset);
Vector2D center = new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2);
s.CeilSlope = new Vector3D(new Vector2D(s.CeilSlope.x, s.CeilSlope.y).GetRotated(rotation), s.CeilSlope.z);
s.CeilSlopeOffset = -Vector3D.DotProduct(s.CeilSlope, new Vector3D(center + relativeoffset, ceiling.GetZ(center)));
Vector3D center = new Vector3D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2, s.CeilHeight);
Plane p = new Plane(center, s.CeilSlope.GetAngleXY() + rotation + Angle2D.PIHALF, -s.CeilSlope.GetAngleZ(), false);
s.CeilSlope = p.Normal;
s.CeilSlopeOffset = p.Offset;
}
}
}

View file

@ -94,8 +94,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
continue;
}
if(!id.IsImageLoaded) id.LoadImage();
Bitmap bmp = id.GetBitmap();
Bitmap bmp = id.ExportBitmap();
lock (bmp)
{
bmp.Save(Path.Combine(settings.ObjPath, Path.GetFileNameWithoutExtension(s) + ".PNG"), ImageFormat.Png);
@ -122,8 +121,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
continue;
}
if(!id.IsImageLoaded) id.LoadImage();
Bitmap bmp = id.GetBitmap();
Bitmap bmp = id.ExportBitmap();
// Handle duplicate names
string flatname = s;

View file

@ -1174,7 +1174,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
mode.SetActionResult("Auto-aligned textures " + rest + ".");
// Make sure the texture is loaded (we need the texture size)
if(!base.Texture.IsImageLoaded) base.Texture.LoadImage();
if(!base.Texture.IsImageLoaded) base.Texture.LoadImageNow();
if(mode.IsSingleSelection)
{

View file

@ -3143,7 +3143,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
BaseVisualGeometrySidedef side = (BaseVisualGeometrySidedef)i;
// Make sure the texture is loaded (we need the texture size)
if(!side.Texture.IsImageLoaded) side.Texture.LoadImage();
if(!side.Texture.IsImageLoaded) side.Texture.LoadImageNow();
//Align textures
AutoAlignTextures(side, side.Texture, alignX, alignY, false, false);

View file

@ -301,7 +301,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Check if the texture is loaded
ImageData sprite = sprites[i];
if (!sprite.IsImageLoaded && !sprite.LoadFailed)
sprite.LoadImage();
sprite.LoadImageNow();
if(sprite.IsImageLoaded)
{
base.textures[i] = sprite;
@ -354,7 +354,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
isloaded = false;
base.textures[i] = General.Map.Data.Hourglass3D;
base.textures[i] = sprite;
// Determine sprite size
float radius = Math.Min(thingradius, thingheight / 2f);

View file

@ -523,36 +523,34 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(!BuilderPlug.Me.AlphaBasedTextureHighlighting || !Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked))
return true;
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
Bitmap image = Texture.GetBitmap();
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
int imageWidth = Texture.GetAlphaTestWidth();
int imageHeight = Texture.GetAlphaTestHeight();
lock (image)
{
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * image.Width) % image.Width;
o.y = (o.y * image.Height) % image.Height;
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * imageWidth) % imageWidth;
o.y = (o.y * imageHeight) % imageHeight;
// Make sure coordinates are inside of texture dimensions...
if (o.x < 0) o.x += image.Width;
if (o.y < 0) o.y += image.Height;
// Make sure coordinates are inside of texture dimensions...
if (o.x < 0) o.x += imageWidth;
if (o.y < 0) o.y += imageHeight;
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, image.Width - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, image.Height - 1);
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, imageWidth - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, imageHeight - 1);
// Check pixel alpha
return (image.GetPixel(ox, oy).A > 0);
}
// Check pixel alpha
return Texture.AlphaTestPixel(ox, oy);
}
return false;

View file

@ -456,35 +456,33 @@ namespace CodeImp.DoomBuilder.BuilderModes
return true;
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
Bitmap image = Texture.GetBitmap();
int imageWidth = Texture.GetAlphaTestWidth();
int imageHeight = Texture.GetAlphaTestHeight();
lock (image)
{
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Fetch ZDoom fields
float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f));
Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f));
Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f));
Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight);
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * image.Width) % image.Width;
o.y = (o.y * image.Height) % image.Height;
// Texture coordinates
Vector2D o = pickintersect;
o = o.GetRotated(rotate);
o.y = -o.y;
o = (o + offset) * scale * texscale;
o.x = (o.x * imageWidth) % imageWidth;
o.y = (o.y * imageHeight) % imageHeight;
// Make sure coordinates are inside of texture dimensions...
if (o.x < 0) o.x += image.Width;
if (o.y < 0) o.y += image.Height;
// Make sure coordinates are inside of texture dimensions...
if (o.x < 0) o.x += imageWidth;
if (o.y < 0) o.y += imageHeight;
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, image.Width - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, image.Height - 1);
// Make final texture coordinates...
int ox = General.Clamp((int)Math.Floor(o.x), 0, imageWidth - 1);
int oy = General.Clamp((int)Math.Floor(o.y), 0, imageHeight - 1);
// Check pixel alpha
return (image.GetPixel(ox, oy).A > 0);
}
// Check pixel alpha
return Texture.AlphaTestPixel(ox, oy);
}
return false;

View file

@ -344,29 +344,27 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(Sidedef != Sidedef.Line.Front) u = 1.0f - u;
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
Bitmap image = Texture.GetBitmap();
int imageWidth = Texture.GetAlphaTestWidth();
int imageHeight = Texture.GetAlphaTestHeight();
lock (image)
{
// Determine texture scale...
Vector2D imgscale = new Vector2D((float)Texture.Width / image.Width, (float)Texture.Height / image.Height);
Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale;
// Determine texture scale...
Vector2D imgscale = new Vector2D((float)Texture.Width / imageWidth, (float)Texture.Height / imageHeight);
Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale;
// Get correct offset to texture space...
float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid");
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / texscale.x + (texoffsetx / imgscale.x)) % image.Width);
// Get correct offset to texture space...
float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid");
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / texscale.x + (texoffsetx / imgscale.x)) % imageWidth);
float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid");
int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / texscale.y - (texoffsety / imgscale.y)) % image.Height);
float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid");
int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / texscale.y - (texoffsety / imgscale.y)) % imageHeight);
// Make sure offsets are inside of texture dimensions...
if (ox < 0) ox += image.Width;
if (oy < 0) oy += image.Height;
// Make sure offsets are inside of texture dimensions...
if (ox < 0) ox += imageWidth;
if (oy < 0) oy += imageHeight;
// Check pixel alpha
Point pixelpos = new Point(General.Clamp(ox, 0, image.Width - 1), General.Clamp(image.Height - oy, 0, image.Height - 1));
return (image.GetPixel(pixelpos.X, pixelpos.Y).A > 0 && base.PickAccurate(@from, to, dir, ref u_ray));
}
// Check pixel alpha
Point pixelpos = new Point(General.Clamp(ox, 0, imageWidth - 1), General.Clamp(imageHeight - oy, 0, imageHeight - 1));
return (Texture.AlphaTestPixel(pixelpos.X, pixelpos.Y) && base.PickAccurate(@from, to, dir, ref u_ray));
}
// Return texture name

View file

@ -296,43 +296,41 @@ namespace CodeImp.DoomBuilder.BuilderModes
new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u);
if(Sidedef != Sidedef.Line.Front) u = 1.0f - u;
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
Bitmap image = Texture.GetBitmap();
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
int imageWidth = Texture.GetAlphaTestWidth();
int imageHeight = Texture.GetAlphaTestHeight();
lock (image)
// Determine texture scale...
Vector2D imgscale = new Vector2D((float)Texture.Width / imageWidth, (float)Texture.Height / imageHeight);
Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale;
// Get correct offset to texture space...
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(Sidedef.Fields, "scalex_mid", 1.0f) / texscale.x
+ ((Sidedef.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid")) / imgscale.x))
% imageWidth);
int oy;
if (repeatmidtex)
{
// Determine texture scale...
Vector2D imgscale = new Vector2D((float)Texture.Width / image.Width, (float)Texture.Height / image.Height);
Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale;
// Get correct offset to texture space...
int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(Sidedef.Fields, "scalex_mid", 1.0f) / texscale.x
+ ((Sidedef.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid")) / imgscale.x))
% image.Width);
int oy;
if (repeatmidtex)
{
bool pegbottom = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
float zoffset = (pegbottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilHeight);
oy = (int)Math.Floor(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y
- ((Sidedef.OffsetY - UniFields.GetFloat(Sidedef.Fields, "offsety_mid")) / imgscale.y))
% image.Height);
}
else
{
float zoffset = bottomclipplane.GetZ(pickintersect);
oy = (int)Math.Ceiling(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y) % image.Height);
}
// Make sure offsets are inside of texture dimensions...
if (ox < 0) ox += image.Width;
if (oy < 0) oy += image.Height;
// Check pixel alpha
Point pixelpos = new Point(General.Clamp(ox, 0, image.Width - 1), General.Clamp(image.Height - oy, 0, image.Height - 1));
return (image.GetPixel(pixelpos.X, pixelpos.Y).A > 0 && base.PickAccurate(from, to, dir, ref u_ray));
bool pegbottom = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
float zoffset = (pegbottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilHeight);
oy = (int)Math.Floor(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y
- ((Sidedef.OffsetY - UniFields.GetFloat(Sidedef.Fields, "offsety_mid")) / imgscale.y))
% imageHeight);
}
else
{
float zoffset = bottomclipplane.GetZ(pickintersect);
oy = (int)Math.Ceiling(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y) % imageHeight);
}
// Make sure offsets are inside of texture dimensions...
if (ox < 0) ox += imageWidth;
if (oy < 0) oy += imageHeight;
// Check pixel alpha
Point pixelpos = new Point(General.Clamp(ox, 0, imageWidth - 1), General.Clamp(imageHeight - oy, 0, imageHeight - 1));
return (Texture.AlphaTestPixel(pixelpos.X, pixelpos.Y) && base.PickAccurate(from, to, dir, ref u_ray));
}
// Return texture name

View file

@ -280,7 +280,7 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer
image = new DynamicBitmapImage(canvas, "_CANVAS_");
image.UseColorCorrection = false;
image.MipMapLevels = 1;
image.LoadImage();
image.LoadImageNow();
// Make custom presentation
CustomPresentation p = new CustomPresentation();