- Fixed some visual mode editing bugs

- Fixed highlight and selection in visual mode when shader model 2.0 is not available
- Added option to turn off glow animation of highlight and selection in visual mode
This commit is contained in:
codeimp 2009-05-04 06:13:56 +00:00
parent d3c87b2a71
commit b5491b4b08
9 changed files with 262 additions and 34 deletions

View file

@ -667,6 +667,7 @@
<Compile Include="Controls\ThingBrowserControl.Designer.cs">
<DependentUpon>ThingBrowserControl.cs</DependentUpon>
</Compile>
<Compile Include="Data\ColorImage.cs" />
<Compile Include="Data\HighResImage.cs" />
<Compile Include="Data\PK3FileImage.cs" />
<Compile Include="Data\PK3StructuredReader.cs" />

View file

@ -73,6 +73,7 @@ namespace CodeImp.DoomBuilder.Config
private int previewimagesize;
private int autoscrollspeed;
private bool showerrorswindow;
private bool animatevisualselection;
// These are not stored in the configuration, only used at runtime
private string defaulttexture;
@ -115,6 +116,7 @@ namespace CodeImp.DoomBuilder.Config
public int PreviewImageSize { get { return previewimagesize; } internal set { previewimagesize = value; } }
public int AutoScrollSpeed { get { return autoscrollspeed; } internal set { autoscrollspeed = value; } }
public bool ShowErrorsWindow { get { return showerrorswindow; } internal set { showerrorswindow = value; } }
public bool AnimateVisualSelection { get { return animatevisualselection; } internal set { animatevisualselection = value; } }
public string DefaultTexture { get { return defaulttexture; } set { defaulttexture = value; } }
public string DefaultFloorTexture { get { return defaultfloortexture; } set { defaultfloortexture = value; } }
@ -173,6 +175,7 @@ namespace CodeImp.DoomBuilder.Config
previewimagesize = cfg.ReadSetting("previewimagesize", 1);
autoscrollspeed = cfg.ReadSetting("autoscrollspeed", 0);
showerrorswindow = cfg.ReadSetting("showerrorswindow", true);
animatevisualselection = cfg.ReadSetting("animatevisualselection", true);
// Success
return true;
@ -213,6 +216,7 @@ namespace CodeImp.DoomBuilder.Config
cfg.WriteSetting("previewimagesize", previewimagesize);
cfg.WriteSetting("autoscrollspeed", autoscrollspeed);
cfg.WriteSetting("showerrorswindow", showerrorswindow);
cfg.WriteSetting("animatevisualselection", animatevisualselection);
// Save settings configuration
General.WriteLogLine("Saving program configuration...");

View file

@ -0,0 +1,105 @@

#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.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Rendering;
#endregion
namespace CodeImp.DoomBuilder.Data
{
internal sealed unsafe class ColorImage : ImageData
{
#region ================== Variables
private PixelColor color;
#endregion
#region ================== Constructor / Disposer
// Constructor
public ColorImage(PixelColor color, int width, int height)
{
// Initialize
this.width = width;
this.height = height;
this.color = color;
SetName(color.ToColorValue().ToString());
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
// This loads the image
protected override void LocalLoadImage()
{
// Leave when already loaded
if(this.IsImageLoaded) return;
if((width == 0) || (height == 0)) return;
lock(this)
{
// Create bitmap
try
{
if(bitmap != null) bitmap.Dispose();
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
PixelColor* pixels = (PixelColor*)bitmapdata.Scan0.ToPointer();
for(int i = 0; i < (width * height); i++)
{
*pixels = color;
pixels++;
}
bitmap.UnlockBits(bitmapdata);
}
catch(Exception e)
{
// Unable to make bitmap
General.ErrorLogger.Add(ErrorType.Error, "Unable to create color image '" + this.Name + "'. " + e.GetType().Name + ": " + e.Message);
loadfailed = true;
}
// Dispose bitmap if load failed
if(loadfailed && (bitmap != null))
{
bitmap.Dispose();
bitmap = null;
}
// Pass on to base
base.LocalLoadImage();
}
}
#endregion
}
}

View file

@ -80,6 +80,8 @@ namespace CodeImp.DoomBuilder.Rendering
// Highlighting
private IVisualPickable highlighted;
private float highlightglow;
private ColorImage highlightimage;
private ColorImage selectionimage;
// Geometry to be rendered.
// Each Dictionary in the array is a render pass.
@ -115,6 +117,7 @@ namespace CodeImp.DoomBuilder.Rendering
CreateProjection();
CreateMatrices2D();
SetupThingCage();
SetupTextures();
renderthingcages = true;
// Dummy frustum
@ -133,7 +136,11 @@ namespace CodeImp.DoomBuilder.Rendering
{
// Clean up
if(thingcage != null) thingcage.Dispose();
if(selectionimage != null) selectionimage.Dispose();
if(highlightimage != null) highlightimage.Dispose();
thingcage = null;
selectionimage = null;
highlightimage = null;
// Done
base.Dispose();
@ -150,7 +157,11 @@ namespace CodeImp.DoomBuilder.Rendering
{
crosshairverts = null;
if(thingcage != null) thingcage.Dispose();
if(selectionimage != null) selectionimage.Dispose();
if(highlightimage != null) highlightimage.Dispose();
thingcage = null;
selectionimage = null;
highlightimage = null;
}
// This is called resets when the device is reset
@ -159,6 +170,7 @@ namespace CodeImp.DoomBuilder.Rendering
{
CreateMatrices2D();
SetupThingCage();
SetupTextures();
}
// This makes screen vertices for display
@ -196,8 +208,23 @@ namespace CodeImp.DoomBuilder.Rendering
#endregion
#region ================== Thing Cage
#region ================== Resources
// This loads the textures for highlight and selection if we need them
private void SetupTextures()
{
if(!graphics.Shaders.Enabled)
{
highlightimage = new ColorImage(General.Colors.Highlight, 32, 32);
highlightimage.LoadImage();
highlightimage.CreateTexture();
selectionimage = new ColorImage(General.Colors.Selection, 32, 32);
selectionimage.LoadImage();
selectionimage.CreateTexture();
}
}
// This sets up the thing cage
private void SetupThingCage()
{
@ -357,7 +384,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This starts rendering
public bool Start()
{
// Create thing box texture if needed
// Create texture
if(General.Map.Data.ThingBox.Texture == null)
General.Map.Data.ThingBox.CreateTexture();
@ -392,9 +419,16 @@ namespace CodeImp.DoomBuilder.Rendering
ApplyMatrices3D();
// Highlight
double time = General.Clock.GetCurrentTime();
highlightglow = (float)Math.Sin(time / 100.0f) * 0.3f + 0.4f;
if(General.Settings.AnimateVisualSelection)
{
double time = General.Clock.GetCurrentTime();
highlightglow = (float)Math.Sin(time / 100.0f) * 0.3f + 0.4f;
}
else
{
highlightglow = 0.6f;
}
// Determine shader pass to use
if(fullbrightness) shaderpass = 1; else shaderpass = 0;
@ -541,7 +575,7 @@ namespace CodeImp.DoomBuilder.Rendering
curtexture.CreateTexture();
// Apply texture
graphics.Device.SetTexture(0, curtexture.Texture);
if(!graphics.Shaders.Enabled) graphics.Device.SetTexture(0, curtexture.Texture);
graphics.Shaders.World3D.Texture1 = curtexture.Texture;
// Go for all geometry that uses this texture
@ -582,12 +616,20 @@ namespace CodeImp.DoomBuilder.Rendering
currentshaderpass = wantedshaderpass;
}
// Set the color to use
Color4 highlightcolor = new Color4(0);
if(g.Selected) highlightcolor = General.Colors.Selection.ToColorValue(highlightglow);
if(g == highlighted) highlightcolor = Color4.Lerp(highlightcolor, General.Colors.Highlight.ToColorValue(), highlightglow);
graphics.Shaders.World3D.SetHighlightColor(highlightcolor.ToArgb());
graphics.Shaders.World3D.ApplySettings();
// Set the colors to use
if(!graphics.Shaders.Enabled)
{
graphics.Device.SetTexture(2, g.Selected ? selectionimage.Texture : null);
graphics.Device.SetTexture(3, (g == highlighted) ? highlightimage.Texture : null);
}
else
{
Color4 highlightcolor = new Color4(1f, 0f, 0f, 0f);
if(g.Selected) highlightcolor = General.Colors.Selection.ToColorValue(highlightglow);
if(g == highlighted) highlightcolor = Color4.Lerp(highlightcolor, General.Colors.Highlight.ToColorValue(), highlightglow);
graphics.Shaders.World3D.SetHighlightColor(highlightcolor.ToArgb());
graphics.Shaders.World3D.ApplySettings();
}
// Render!
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
@ -622,7 +664,7 @@ namespace CodeImp.DoomBuilder.Rendering
curtexture.CreateTexture();
// Apply texture
graphics.Device.SetTexture(0, curtexture.Texture);
if(!graphics.Shaders.Enabled) graphics.Device.SetTexture(0, curtexture.Texture);
graphics.Shaders.World3D.Texture1 = curtexture.Texture;
// Render all things with this texture
@ -645,11 +687,19 @@ namespace CodeImp.DoomBuilder.Rendering
currentshaderpass = wantedshaderpass;
}
// Set the color to use
Color4 highlightcolor = new Color4(0);
if(t.Selected) highlightcolor = General.Colors.Selection.ToColorValue(highlightglow);
if(t == highlighted) highlightcolor = Color4.Lerp(highlightcolor, General.Colors.Highlight.ToColorValue(), highlightglow);
graphics.Shaders.World3D.SetHighlightColor(highlightcolor.ToArgb());
// Set the colors to use
if(!graphics.Shaders.Enabled)
{
graphics.Device.SetTexture(2, t.Selected ? selectionimage.Texture : null);
graphics.Device.SetTexture(3, (t == highlighted) ? highlightimage.Texture : null);
}
else
{
Color4 highlightcolor = new Color4(1f, 0f, 0f, 0f);
if(t.Selected) highlightcolor = General.Colors.Selection.ToColorValue(highlightglow);
if(t == highlighted) highlightcolor = Color4.Lerp(highlightcolor, General.Colors.Highlight.ToColorValue(), highlightglow);
graphics.Shaders.World3D.SetHighlightColor(highlightcolor.ToArgb());
}
// Create the matrix for positioning / rotation
world = t.Orientation;

View file

@ -176,10 +176,11 @@ namespace CodeImp.DoomBuilder.Rendering
device.SetSamplerState(0, SamplerState.AddressU, TextureAddress.Wrap);
device.SetSamplerState(0, SamplerState.AddressV, TextureAddress.Wrap);
device.SetSamplerState(0, SamplerState.AddressW, TextureAddress.Wrap);
// First texture stage
if(index == 0)
if((index == 0) || (index == 2))
{
// Normal
device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.Modulate);
device.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.ColorArg2, TextureArgument.Diffuse);
@ -188,11 +189,17 @@ namespace CodeImp.DoomBuilder.Rendering
}
else
{
// Full brightness
device.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.ResultArg, TextureArgument.Current);
device.SetTextureStageState(0, TextureStage.TexCoordIndex, 0);
}
// First alpha stage
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);
device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
// Second texture stage
device.SetTextureStageState(1, TextureStage.ColorOperation, TextureOperation.Modulate);
@ -201,21 +208,48 @@ namespace CodeImp.DoomBuilder.Rendering
device.SetTextureStageState(1, TextureStage.ResultArg, TextureArgument.Current);
device.SetTextureStageState(1, TextureStage.TexCoordIndex, 0);
// No more further stages
device.SetTextureStageState(2, TextureStage.ColorOperation, TextureOperation.Disable);
// First alpha stage
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);
device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
// Second alpha stage
device.SetTextureStageState(1, TextureStage.AlphaOperation, TextureOperation.Modulate);
device.SetTextureStageState(1, TextureStage.AlphaArg1, TextureArgument.Current);
device.SetTextureStageState(1, TextureStage.AlphaArg2, TextureArgument.TFactor);
// No more further stages
device.SetTextureStageState(2, TextureStage.AlphaOperation, TextureOperation.Disable);
// Highlight?
if(index > 1)
{
// Third texture stage
device.SetTextureStageState(2, TextureStage.ColorOperation, TextureOperation.AddSigned);
device.SetTextureStageState(2, TextureStage.ColorArg1, TextureArgument.Current);
device.SetTextureStageState(2, TextureStage.ColorArg2, TextureArgument.Texture);
device.SetTextureStageState(2, TextureStage.ColorArg0, TextureArgument.Texture);
device.SetTextureStageState(2, TextureStage.ResultArg, TextureArgument.Current);
device.SetTextureStageState(2, TextureStage.TexCoordIndex, 0);
// Third alpha stage
device.SetTextureStageState(2, TextureStage.AlphaOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(2, TextureStage.AlphaArg1, TextureArgument.Current);
// Fourth texture stage
device.SetTextureStageState(3, TextureStage.ColorOperation, TextureOperation.AddSigned);
device.SetTextureStageState(3, TextureStage.ColorArg1, TextureArgument.Current);
device.SetTextureStageState(3, TextureStage.ColorArg2, TextureArgument.Texture);
device.SetTextureStageState(3, TextureStage.ColorArg0, TextureArgument.Texture);
device.SetTextureStageState(3, TextureStage.ResultArg, TextureArgument.Current);
device.SetTextureStageState(3, TextureStage.TexCoordIndex, 0);
// Fourth alpha stage
device.SetTextureStageState(3, TextureStage.AlphaOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(3, TextureStage.AlphaArg1, TextureArgument.Current);
// No more further stages
device.SetTextureStageState(4, TextureStage.ColorOperation, TextureOperation.Disable);
device.SetTextureStageState(4, TextureStage.AlphaOperation, TextureOperation.Disable);
}
else
{
// No more further stages
device.SetTextureStageState(2, TextureStage.ColorOperation, TextureOperation.Disable);
device.SetTextureStageState(2, TextureStage.AlphaOperation, TextureOperation.Disable);
}
}
base.BeginPass(index);

View file

@ -112,6 +112,7 @@ namespace CodeImp.DoomBuilder.Windows
this.colorlinenumbers = new CodeImp.DoomBuilder.Controls.ColorControl();
this.colorcomments = new CodeImp.DoomBuilder.Controls.ColorControl();
this.colorplaintext = new CodeImp.DoomBuilder.Controls.ColorControl();
this.animatevisualselection = new System.Windows.Forms.CheckBox();
label7 = new System.Windows.Forms.Label();
label6 = new System.Windows.Forms.Label();
label5 = new System.Windows.Forms.Label();
@ -901,6 +902,7 @@ namespace CodeImp.DoomBuilder.Windows
//
// tabcolors
//
this.tabcolors.Controls.Add(this.animatevisualselection);
this.tabcolors.Controls.Add(this.squarethings);
this.tabcolors.Controls.Add(this.visualbilinear);
this.tabcolors.Controls.Add(this.classicbilinear);
@ -1122,6 +1124,16 @@ namespace CodeImp.DoomBuilder.Windows
this.colorplaintext.Size = new System.Drawing.Size(150, 23);
this.colorplaintext.TabIndex = 2;
//
// animatevisualselection
//
this.animatevisualselection.AutoSize = true;
this.animatevisualselection.Location = new System.Drawing.Point(448, 356);
this.animatevisualselection.Name = "animatevisualselection";
this.animatevisualselection.Size = new System.Drawing.Size(188, 18);
this.animatevisualselection.TabIndex = 23;
this.animatevisualselection.Text = "Animate selection in visual modes";
this.animatevisualselection.UseVisualStyleBackColor = true;
//
// PreferencesForm
//
this.AcceptButton = this.apply;
@ -1252,5 +1264,6 @@ namespace CodeImp.DoomBuilder.Windows
private Dotnetrix.Controls.TrackBar autoscrollspeed;
private System.Windows.Forms.Label autoscrollspeedlabel;
private System.Windows.Forms.Label label15;
private System.Windows.Forms.CheckBox animatevisualselection;
}
}

View file

@ -69,6 +69,7 @@ namespace CodeImp.DoomBuilder.Windows
scriptontop.Checked = General.Settings.ScriptOnTop;
previewsize.Value = General.Settings.PreviewImageSize;
autoscrollspeed.Value = General.Settings.AutoScrollSpeed;
animatevisualselection.Checked = General.Settings.AnimateVisualSelection;
// Fill fonts list
scriptfontname.BeginUpdate();
@ -169,7 +170,8 @@ namespace CodeImp.DoomBuilder.Windows
General.Settings.ScriptOnTop = scriptontop.Checked;
General.Settings.PreviewImageSize = previewsize.Value;
General.Settings.AutoScrollSpeed = autoscrollspeed.Value;
General.Settings.AnimateVisualSelection = animatevisualselection.Checked;
// Script font size
int fontsize = 8;
int.TryParse(scriptfontsize.Text, out fontsize);

View file

@ -321,6 +321,9 @@
<metadata name="tabcolors.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="animatevisualselection.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="squarethings.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>

View file

@ -177,7 +177,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if(!string.IsNullOrEmpty(actionresult.displaystatus))
General.Interface.DisplayStatus(StatusType.Action, actionresult.displaystatus);
// Reset changed flags
foreach(KeyValuePair<Sector, VisualSector> vs in allsectors)
{
BaseVisualSector bvs = (vs.Value as BaseVisualSector);
bvs.Floor.Changed = false;
bvs.Ceiling.Changed = false;
}
lastaction = General.Actions.Current;
selectionchanged = false;
@ -348,7 +356,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
{
BaseVisualThing bvt = (BaseVisualThing)vt.Value;
if(bvt.Changed) bvt.Setup();
if(bvt.Changed) bvt.Rebuild();
}
}
@ -492,9 +500,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Apply texture offsets
public void ApplyTextureOffsetChange(int dx, int dy)
{
Dictionary<Sidedef, int> donesides = new Dictionary<Sidedef, int>(selectedobjects.Count);
foreach(IVisualEventReceiver i in selectedobjects)
{
i.OnChangeTextureOffset(dx, dy);
if(i is BaseVisualGeometrySidedef)
{
if(!donesides.ContainsKey((i as BaseVisualGeometrySidedef).Sidedef))
{
i.OnChangeTextureOffset(dx, dy);
donesides.Add((i as BaseVisualGeometrySidedef).Sidedef, 0);
}
}
}
}