thing in cages

This commit is contained in:
codeimp 2008-12-14 23:24:40 +00:00
parent 4aa53860c6
commit 27f4acac04
9 changed files with 205 additions and 6 deletions

BIN
Resources/ThingBox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

View file

@ -652,6 +652,7 @@
<EmbeddedResource Include="Resources\Crosshair.png" />
<EmbeddedResource Include="Resources\CrosshairBusy.png" />
<Content Include="Resources\DB2.ico" />
<EmbeddedResource Include="Resources\ThingBox.png" />
<EmbeddedResource Include="Resources\Nothing.png" />
<EmbeddedResource Include="Resources\UnknownThing.png" />
<Compile Include="VisualModes\IVisualPickable.cs" />

View file

@ -122,7 +122,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.Texture = General.Map.Data.Hourglass3D;
// Determine sprite size
float radius = info.Width * 0.5f;
float radius = info.Width;
float height = info.Height;
// Make vertices
@ -137,10 +137,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
// Setup position
// Setup position and size
Vector3D pos = Thing.Position;
if(Thing.Sector != null) pos.z += Thing.Sector.FloorHeight;
SetPosition(pos);
SetCageSize(info.Width, info.Height);
SetCageColor(Thing.Color);
// Done
return true;

View file

@ -75,6 +75,7 @@ namespace CodeImp.DoomBuilder.Data
private ImageData crosshair;
private ImageData crosshairbusy;
private Dictionary<string, ImageData> internalsprites;
private ImageData thingbox;
// Used images
private Dictionary<long, long> usedimages;
@ -97,6 +98,7 @@ namespace CodeImp.DoomBuilder.Data
public ImageData Hourglass3D { get { return hourglass3d; } }
public ImageData Crosshair3D { get { return crosshair; } }
public ImageData CrosshairBusy3D { get { return crosshairbusy; } }
public ImageData ThingBox { get { return thingbox; } }
internal ICollection<MatchingTextureSet> TextureSets { get { return texturesets; } }
internal OthersTextureSet OthersTextureSet { get { return othertextures; } }
@ -134,6 +136,8 @@ namespace CodeImp.DoomBuilder.Data
crosshair.LoadImage();
crosshairbusy = new ResourceImage("CrosshairBusy.png");
crosshairbusy.LoadImage();
thingbox = new ResourceImage("ThingBox.png");
thingbox.LoadImage();
}
// Disposer
@ -152,6 +156,8 @@ namespace CodeImp.DoomBuilder.Data
crosshair = null;
crosshairbusy.Dispose();
crosshairbusy = null;
thingbox.Dispose();
thingbox = null;
// Done
isdisposed = true;

View file

@ -57,6 +57,7 @@ namespace CodeImp.DoomBuilder.Rendering
private Matrix worldviewproj;
private Matrix view2d;
private Matrix world;
private Vector3D cameraposition;
// Window size
private Size windowsize;
@ -64,6 +65,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Frustum
private ProjectedFrustum2D frustum;
// Thing cage
private VertexBuffer thingcage;
// Crosshair
private FlatVertex[] crosshairverts;
private bool crosshairbusy;
@ -80,6 +84,9 @@ namespace CodeImp.DoomBuilder.Rendering
// Each VisualThing is inserted in the Dictionary by their texture image.
private Dictionary<ImageData, List<VisualThing>>[] things;
// Things to be rendered, sorted by distance from camera
private BinaryHeap<VisualThing> thingsbydistance;
#endregion
#region ================== Properties
@ -96,6 +103,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Initialize
CreateProjection();
CreateMatrices2D();
SetupThingCage();
// Dummy frustum
frustum = new ProjectedFrustum2D(new Vector2D(), 0.0f, 0.0f, PROJ_NEAR_PLANE,
@ -112,7 +120,9 @@ namespace CodeImp.DoomBuilder.Rendering
if(!isdisposed)
{
// Clean up
if(thingcage != null) thingcage.Dispose();
thingcage = null;
// Done
base.Dispose();
}
@ -127,6 +137,8 @@ namespace CodeImp.DoomBuilder.Rendering
public override void UnloadResource()
{
crosshairverts = null;
if(thingcage != null) thingcage.Dispose();
thingcage = null;
}
// This is called resets when the device is reset
@ -134,6 +146,7 @@ namespace CodeImp.DoomBuilder.Rendering
public override void ReloadResource()
{
CreateMatrices2D();
SetupThingCage();
}
// This makes screen vertices for display
@ -171,6 +184,84 @@ namespace CodeImp.DoomBuilder.Rendering
#endregion
#region ================== Thing Cage
// This sets up the thing cage
private void SetupThingCage()
{
const int totalvertices = 36;
WorldVertex[] tv = new WorldVertex[totalvertices];
float x0 = -1.0f;
float x1 = 1.0f;
float y0 = -1.0f;
float y1 = 1.0f;
float z0 = 0.0f;
float z1 = 1.0f;
float u0 = 0.0f;
float u1 = 1.0f;
float v0 = 0.0f;
float v1 = 1.0f;
int c = -1;
// Front
tv[0] = new WorldVertex(x0, y0, z0, c, u0, v0);
tv[1] = new WorldVertex(x0, y0, z1, c, u0, v1);
tv[2] = new WorldVertex(x1, y0, z0, c, u1, v0);
tv[3] = new WorldVertex(x1, y0, z0, c, u1, v0);
tv[4] = new WorldVertex(x0, y0, z1, c, u0, v1);
tv[5] = new WorldVertex(x1, y0, z1, c, u1, v1);
// Right
tv[6] = new WorldVertex(x1, y0, z0, c, u0, v0);
tv[7] = new WorldVertex(x1, y0, z1, c, u0, v1);
tv[8] = new WorldVertex(x1, y1, z0, c, u1, v0);
tv[9] = new WorldVertex(x1, y1, z0, c, u1, v0);
tv[10] = new WorldVertex(x1, y0, z1, c, u0, v1);
tv[11] = new WorldVertex(x1, y1, z1, c, u1, v1);
// Back
tv[12] = new WorldVertex(x1, y1, z0, c, u0, v0);
tv[13] = new WorldVertex(x1, y1, z1, c, u0, v1);
tv[14] = new WorldVertex(x0, y1, z0, c, u1, v0);
tv[15] = new WorldVertex(x0, y1, z0, c, u1, v0);
tv[16] = new WorldVertex(x1, y1, z1, c, u0, v1);
tv[17] = new WorldVertex(x0, y1, z1, c, u1, v1);
// Left
tv[18] = new WorldVertex(x0, y1, z0, c, u0, v1);
tv[19] = new WorldVertex(x0, y1, z1, c, u0, v0);
tv[20] = new WorldVertex(x0, y0, z1, c, u1, v0);
tv[21] = new WorldVertex(x0, y1, z0, c, u1, v0);
tv[22] = new WorldVertex(x0, y0, z1, c, u0, v1);
tv[23] = new WorldVertex(x0, y0, z0, c, u1, v1);
// Top
tv[24] = new WorldVertex(x0, y0, z1, c, u0, v0);
tv[25] = new WorldVertex(x0, y1, z1, c, u0, v1);
tv[26] = new WorldVertex(x1, y0, z1, c, u1, v0);
tv[27] = new WorldVertex(x1, y0, z1, c, u1, v0);
tv[28] = new WorldVertex(x0, y1, z1, c, u0, v1);
tv[29] = new WorldVertex(x1, y1, z1, c, u1, v1);
// Bottom
tv[30] = new WorldVertex(x1, y0, z0, c, u1, v0);
tv[31] = new WorldVertex(x0, y1, z0, c, u0, v1);
tv[32] = new WorldVertex(x0, y0, z0, c, u0, v0);
tv[33] = new WorldVertex(x1, y0, z0, c, u1, v0);
tv[34] = new WorldVertex(x1, y1, z0, c, u1, v1);
tv[35] = new WorldVertex(x0, y1, z0, c, u0, v1);
// Create vertexbuffer
thingcage = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * totalvertices,
Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
DataStream bufferstream = thingcage.Lock(0, WorldVertex.Stride * totalvertices, LockFlags.Discard);
bufferstream.WriteRange<WorldVertex>(tv);
thingcage.Unlock();
bufferstream.Dispose();
}
#endregion
#region ================== Presentation
// This creates the projection
@ -204,6 +295,7 @@ namespace CodeImp.DoomBuilder.Rendering
float anglexy, anglez;
// Calculate delta vector
cameraposition = pos;
delta = lookat - pos;
anglexy = delta.GetAngleXY();
anglez = delta.GetAngleZ();
@ -253,6 +345,10 @@ namespace CodeImp.DoomBuilder.Rendering
// This starts rendering
public bool Start()
{
// Create thing box texture if needed
if(General.Map.Data.ThingBox.Texture == null)
General.Map.Data.ThingBox.CreateTexture();
// Start drawing
if(graphics.StartRendering(true, General.Colors.Background.ToColorValue(), graphics.BackBuffer, graphics.DepthBuffer))
{
@ -263,7 +359,6 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Device.SetRenderState(RenderState.FogEnable, false);
graphics.Device.SetRenderState(RenderState.FogDensity, 1.0f);
graphics.Device.SetRenderState(RenderState.FogColor, General.Colors.Background.ToInt());
@ -271,6 +366,8 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.FogEnd, General.Settings.ViewDistance);
graphics.Device.SetRenderState(RenderState.FogTableMode, FogMode.Linear);
graphics.Device.SetRenderState(RenderState.RangeFogEnable, false);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Shaders.World3D.SetModulateColor(-1);
// Matrices
world = Matrix.Identity;
@ -296,6 +393,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Make collection
geometry = new Dictionary<ImageData, BinaryHeap<VisualGeometry>>[RENDER_PASSES];
things = new Dictionary<ImageData, List<VisualThing>>[RENDER_PASSES];
thingsbydistance = new BinaryHeap<VisualThing>();
for(int i = 0; i < RENDER_PASSES; i++)
{
geometry[i] = new Dictionary<ImageData, BinaryHeap<VisualGeometry>>();
@ -342,6 +440,9 @@ namespace CodeImp.DoomBuilder.Rendering
RenderSinglePass((int)RenderPass.Alpha);
graphics.Shaders.World3D.EndPass();
// THINGS
RenderThingCages();
// ADDITIVE PASS
world = Matrix.Identity;
ApplyMatrices3D();
@ -358,6 +459,41 @@ namespace CodeImp.DoomBuilder.Rendering
geometry = null;
}
// This renders all thing cages
private void RenderThingCages()
{
// Set renderstates
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
graphics.Device.SetRenderState(RenderState.ZWriteEnable, false);
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
graphics.Device.SetStreamSource(0, thingcage, 0, WorldVertex.Stride);
graphics.Device.SetTexture(0, General.Map.Data.ThingBox.Texture);
graphics.Shaders.World3D.Texture1 = General.Map.Data.ThingBox.Texture;
graphics.Shaders.World3D.BeginPass(0);
foreach(VisualThing t in thingsbydistance)
{
// Setup matrix
world = Matrix.Multiply(t.CageScales, t.Position);
ApplyMatrices3D();
// Setup color
graphics.Shaders.World3D.SetModulateColor(t.CageColor);
graphics.Device.SetRenderState(RenderState.TextureFactor, t.CageColor);
// Render!
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
}
// Done
graphics.Shaders.World3D.EndPass();
graphics.Shaders.World3D.SetModulateColor(-1);
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
}
// This performs a single render pass
private void RenderSinglePass(int pass)
{
@ -502,6 +638,10 @@ namespace CodeImp.DoomBuilder.Rendering
// Must have a texture!
if(t.Texture != null)
{
// Make sure the distance to camera is calculated
t.CalculateCameraDistance(cameraposition);
thingsbydistance.Add(t);
// Texture group not yet collected?
if(!things[t.RenderPassInt].ContainsKey(t.Texture))
{

View file

@ -45,6 +45,7 @@ namespace CodeImp.DoomBuilder.Rendering
private EffectHandle worldviewproj;
private EffectHandle minfiltersettings;
private EffectHandle magfiltersettings;
private EffectHandle modulatecolor;
#endregion
@ -70,6 +71,7 @@ namespace CodeImp.DoomBuilder.Rendering
texture1 = effect.GetParameter(null, "texture1");
minfiltersettings = effect.GetParameter(null, "minfiltersettings");
magfiltersettings = effect.GetParameter(null, "magfiltersettings");
modulatecolor = effect.GetParameter(null, "modulatecolor");
}
// Initialize world vertex declaration
@ -97,6 +99,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(worldviewproj != null) worldviewproj.Dispose();
if(minfiltersettings != null) minfiltersettings.Dispose();
if(magfiltersettings != null) magfiltersettings.Dispose();
if(modulatecolor != null) modulatecolor.Dispose();
// Done
base.Dispose();
@ -125,6 +128,12 @@ namespace CodeImp.DoomBuilder.Rendering
}
}
// This sets the modulation color
public void SetModulateColor(int modcolor)
{
effect.SetValue<Color4>(modulatecolor, new Color4(modcolor));
}
#endregion
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

View file

@ -17,6 +17,9 @@ struct PixelData
float2 uv : TEXCOORD0;
};
// Modulation color
float4 modulatecolor;
// Matrix for final transformation
float4x4 worldviewproj;
@ -59,7 +62,7 @@ float4 ps_main(PixelData pd) : COLOR
float4 tcolor = tex2D(texturesamp, pd.uv);
// Blend texture color and vertex color
return tcolor * pd.color;
return tcolor * pd.color * modulatecolor;
}
// Technique for shader model 2.0

View file

@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.VisualModes
{
public abstract class VisualThing : IVisualPickable, ID3DResource
public abstract class VisualThing : IVisualPickable, ID3DResource, IComparable<VisualThing>
{
#region ================== Constants
@ -64,7 +64,11 @@ namespace CodeImp.DoomBuilder.VisualModes
private int renderpass;
private Matrix orientation;
private Matrix position;
private Matrix cagescales;
private bool billboard;
private Vector2D pos2d;
private float cameradistance;
private int cagecolor;
// Disposing
private bool isdisposed = false;
@ -79,6 +83,8 @@ namespace CodeImp.DoomBuilder.VisualModes
internal int RenderPassInt { get { return renderpass; } }
internal Matrix Orientation { get { return orientation; } }
internal Matrix Position { get { return position; } }
internal Matrix CageScales { get { return cagescales; } }
internal int CageColor { get { return cagecolor; } }
/// <summary>
/// Set to True to use billboarding for this thing. When using billboarding,
@ -119,6 +125,7 @@ namespace CodeImp.DoomBuilder.VisualModes
this.billboard = true;
this.orientation = Matrix.Identity;
this.position = Matrix.Identity;
this.cagescales = Matrix.Identity;
// Register as resource
General.Map.Graphics.RegisterResource(this);
@ -146,6 +153,12 @@ namespace CodeImp.DoomBuilder.VisualModes
#region ================== Methods
// This sets the distance from the camera
internal void CalculateCameraDistance(Vector2D campos)
{
cameradistance = Vector2D.DistanceSq(pos2d, campos);
}
// This is called before a device is reset
// (when resized or display adapter was changed)
public void UnloadResource()
@ -164,11 +177,28 @@ namespace CodeImp.DoomBuilder.VisualModes
//Update();
}
/// <summary>
/// Sets the size of the cage around the thing geometry.
/// </summary>
public void SetCageSize(float radius, float height)
{
cagescales = Matrix.Scaling(radius, radius, height);
}
/// <summary>
/// Sets the color of the cage around the thing geometry.
/// </summary>
public void SetCageColor(PixelColor color)
{
cagecolor = color.ToInt();
}
/// <summary>
/// This sets the position to use for the thing geometry.
/// </summary>
public void SetPosition(Vector3D pos)
{
pos2d = new Vector2D(pos);
position = Matrix.Translation(D3DDevice.V3(pos));
}
@ -237,6 +267,14 @@ namespace CodeImp.DoomBuilder.VisualModes
return false;
}
/// <summary>
/// This sorts things by distance from the camera. Farthest first.
/// </summary>
public int CompareTo(VisualThing other)
{
return Math.Sign(this.cameradistance - other.cameradistance);
}
#endregion
}
}