mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 12:22:35 +00:00
working on visual mode
This commit is contained in:
parent
22d5b88baf
commit
5db0757020
6 changed files with 205 additions and 64 deletions
|
@ -97,13 +97,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This creates a visual sector
|
||||
protected override VisualSector CreateVisualSector(Sector s)
|
||||
{
|
||||
return new BaseVisualSector(s);
|
||||
BaseVisualSector vs = new BaseVisualSector(s);
|
||||
return vs;
|
||||
}
|
||||
|
||||
// This creates a visual thing
|
||||
protected override VisualThing CreateVisualThing(Thing t)
|
||||
{
|
||||
return new BaseVisualThing(t);
|
||||
BaseVisualThing vt = new BaseVisualThing(t);
|
||||
if(vt.Setup()) return vt; else return null;
|
||||
}
|
||||
|
||||
// This locks the target so that it isn't changed until unlocked
|
||||
|
@ -167,7 +169,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Apply new target
|
||||
target = newtarget;
|
||||
}
|
||||
|
||||
|
||||
// This changes the target's height
|
||||
private void ChangeTargetHeight(int amount)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,8 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -39,29 +41,139 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
internal class BaseVisualThing : VisualThing
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
|
||||
private ThingTypeInfo info;
|
||||
private bool isloaded;
|
||||
private ImageData sprite;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
|
||||
// Constructor
|
||||
public BaseVisualThing(Thing t) : base(t)
|
||||
{
|
||||
// Find thing information
|
||||
info = General.Map.Config.GetThingInfo(Thing.Type);
|
||||
|
||||
// Find sprite texture
|
||||
if(info.Sprite.Length > 0)
|
||||
{
|
||||
sprite = General.Map.Data.GetSpriteImage(info.Sprite);
|
||||
if(sprite != null) sprite.AddReference();
|
||||
}
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
|
||||
// This builds the thing geometry. Returns false when nothing was created.
|
||||
public virtual bool Setup()
|
||||
{
|
||||
if(sprite != null)
|
||||
{
|
||||
// Color to modulate sprite with (god knows what we could use this for)
|
||||
PixelColor pc = new PixelColor(255, 255, 255, 255);
|
||||
|
||||
// Find the sector in which the thing resides
|
||||
Thing.DetermineSector();
|
||||
|
||||
// Check if the texture is loaded
|
||||
isloaded = sprite.IsImageLoaded;
|
||||
if(isloaded)
|
||||
{
|
||||
base.Texture = sprite;
|
||||
|
||||
// Determine sprite size
|
||||
float radius = sprite.ScaledWidth * 0.5f;
|
||||
float height = sprite.ScaledHeight;
|
||||
|
||||
// Determine texture coordinates
|
||||
Vector2D t1 = new Vector2D(1.0f / sprite.ScaledWidth, 1.0f / sprite.ScaledHeight);
|
||||
Vector2D t2 = new Vector2D(1.0f - t1.x, 1.0f - t1.y);
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, pc.ToInt(), t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, pc.ToInt(), t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, pc.ToInt(), t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, pc.ToInt(), t2.x, t2.y);
|
||||
SetVertices(verts);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Texture = General.Map.Data.Hourglass3D;
|
||||
|
||||
// Determine sprite size
|
||||
float radius = info.Width * 0.5f;
|
||||
float height = info.Height;
|
||||
|
||||
// Determine texture coordinates
|
||||
Vector2D t1 = new Vector2D(1.0f / base.Texture.ScaledWidth, 1.0f / base.Texture.ScaledHeight);
|
||||
Vector2D t2 = new Vector2D(1.0f - t1.x, 1.0f - t1.y);
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, pc.ToInt(), t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, pc.ToInt(), t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, pc.ToInt(), t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, pc.ToInt(), t2.x, t2.y);
|
||||
SetVertices(verts);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup position
|
||||
Vector3D pos = Thing.Position;
|
||||
if(Thing.Sector != null) pos.z += Thing.Sector.FloorHeight;
|
||||
SetPosition(pos);
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disposing
|
||||
public override void Dispose()
|
||||
{
|
||||
if(!IsDisposed)
|
||||
{
|
||||
if(sprite != null) sprite.RemoveReference();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
// This updates the thing when needed
|
||||
public override void Update()
|
||||
{
|
||||
if(!isloaded)
|
||||
{
|
||||
// Rebuild sprite geometry when sprite is loaded
|
||||
if(sprite.IsImageLoaded)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Let the base update
|
||||
base.Update();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
lumpdata.Read(membytes, 0, (int)lumpdata.Length);
|
||||
mem = new MemoryStream(membytes);
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
|
||||
// Get a reader for the data
|
||||
reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
|
||||
if(reader is UnknownImageReader)
|
||||
|
@ -80,19 +80,21 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Data is in an unknown format!
|
||||
General.WriteLogLine("WARNING: Sprite lump '" + Name + "' data format could not be read!");
|
||||
}
|
||||
|
||||
|
||||
// Read data as bitmap
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
if(bitmap != null) bitmap.Dispose();
|
||||
bitmap = reader.ReadAsBitmap(mem);
|
||||
if(bitmap == null) return;
|
||||
|
||||
|
||||
// Done
|
||||
mem.Dispose();
|
||||
|
||||
// Get width and height from image
|
||||
width = bitmap.Size.Width;
|
||||
height = bitmap.Size.Height;
|
||||
scaledwidth = (float)bitmap.Size.Width;
|
||||
scaledheight = (float)bitmap.Size.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -54,8 +54,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
private Matrix projection;
|
||||
private Matrix view3d;
|
||||
private Matrix billboard;
|
||||
private Matrix viewproj;
|
||||
private Matrix worldviewproj;
|
||||
private Matrix view2d;
|
||||
private Matrix world;
|
||||
|
||||
// Window size
|
||||
private Size windowsize;
|
||||
|
@ -213,12 +214,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
// Make the view matrix
|
||||
view3d = Matrix.LookAtRH(D3DDevice.V3(pos), D3DDevice.V3(lookat), new Vector3(0f, 0f, 1f));
|
||||
|
||||
|
||||
// Make the billboard matrix
|
||||
Vector3D lookat2d = new Vector3D(lookat.x, lookat.y, 0.0f);
|
||||
Vector3D campos2d = new Vector3D(pos.x, pos.y, 0.0f);
|
||||
Vector3D delta2d = lookat2d - campos2d;
|
||||
billboard = Matrix.Billboard(D3DDevice.V3(lookat2d), D3DDevice.V3(campos2d), new Vector3(0f, 0f, 1f), D3DDevice.V3(delta2d.GetNormal()));
|
||||
billboard = Matrix.RotationZ(anglexy + Angle2D.PI);
|
||||
}
|
||||
|
||||
// This creates 2D view matrix
|
||||
|
@ -233,8 +231,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// This applies the matrices
|
||||
private void ApplyMatrices3D()
|
||||
{
|
||||
viewproj = view3d * projection;
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
worldviewproj = world * view3d * projection;
|
||||
graphics.Shaders.World3D.WorldViewProj = worldviewproj;
|
||||
graphics.Device.SetTransform(TransformState.World, world);
|
||||
graphics.Device.SetTransform(TransformState.Projection, projection);
|
||||
graphics.Device.SetTransform(TransformState.View, view3d);
|
||||
}
|
||||
|
@ -242,7 +241,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// This sets the appropriate view matrix
|
||||
public void ApplyMatrices2D()
|
||||
{
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
graphics.Device.SetTransform(TransformState.World, world);
|
||||
graphics.Device.SetTransform(TransformState.Projection, Matrix.Identity);
|
||||
graphics.Device.SetTransform(TransformState.View, view2d);
|
||||
}
|
||||
|
@ -274,6 +273,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Device.SetRenderState(RenderState.RangeFogEnable, false);
|
||||
|
||||
// Matrices
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
|
||||
// Create crosshair vertices
|
||||
|
@ -314,26 +314,25 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
|
||||
graphics.Shaders.World3D.Begin();
|
||||
graphics.Shaders.World3D.WorldViewProj = viewproj;
|
||||
|
||||
// Matrices
|
||||
ApplyMatrices3D();
|
||||
|
||||
// SOLID PASS
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
graphics.Shaders.World3D.BeginPass(0);
|
||||
RenderSinglePass((int)RenderPass.Solid);
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
|
||||
// MASK PASS
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
|
||||
graphics.Shaders.World3D.BeginPass(0);
|
||||
RenderSinglePass((int)RenderPass.Mask);
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
|
||||
// ALPHA PASS
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
|
||||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.ZWriteEnable, false);
|
||||
|
@ -344,7 +343,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.World3D.EndPass();
|
||||
|
||||
// ADDITIVE PASS
|
||||
graphics.Device.SetTransform(TransformState.World, Matrix.Identity);
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.One);
|
||||
graphics.Shaders.World3D.BeginPass(0);
|
||||
RenderSinglePass((int)RenderPass.Additive);
|
||||
|
@ -424,41 +424,41 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
foreach(KeyValuePair<ImageData, List<VisualThing>> group in thingspass)
|
||||
{
|
||||
ImageData curtexture;
|
||||
|
||||
|
||||
// What texture to use?
|
||||
if((group.Key != null) && group.Key.IsImageLoaded && !group.Key.IsDisposed)
|
||||
curtexture = group.Key;
|
||||
else
|
||||
curtexture = General.Map.Data.Hourglass3D;
|
||||
|
||||
|
||||
// Create Direct3D texture if still needed
|
||||
if((curtexture.Texture == null) || curtexture.Texture.Disposed)
|
||||
curtexture.CreateTexture();
|
||||
|
||||
|
||||
// Apply texture
|
||||
graphics.Device.SetTexture(0, curtexture.Texture);
|
||||
graphics.Shaders.World3D.Texture1 = curtexture.Texture;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
|
||||
|
||||
// Render all things with this texture
|
||||
foreach(VisualThing t in group.Value)
|
||||
{
|
||||
// Update buffer if needed
|
||||
if(t.NeedsUpdateGeo) t.Update();
|
||||
|
||||
|
||||
// Only do this sector when a vertexbuffer is created
|
||||
if(t.GeometryBuffer != null)
|
||||
{
|
||||
// Create the matrix for positioning / rotation
|
||||
Matrix transform = t.Orientation;
|
||||
if(t.Billboard) transform = Matrix.Multiply(transform, billboard);
|
||||
transform = Matrix.Multiply(transform, t.Position);
|
||||
graphics.Device.SetTransform(TransformState.World, transform);
|
||||
world = t.Orientation;
|
||||
if(t.Billboard) world = Matrix.Multiply(world, billboard);
|
||||
world = Matrix.Multiply(world, t.Position);
|
||||
ApplyMatrices3D();
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
|
||||
// Apply buffer
|
||||
graphics.Device.SetStreamSource(0, t.GeometryBuffer, 0, WorldVertex.Stride);
|
||||
|
||||
|
||||
// Render!
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, t.Triangles);
|
||||
}
|
||||
|
|
|
@ -174,7 +174,8 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
public override void OnDisengage()
|
||||
{
|
||||
base.OnDisengage();
|
||||
|
||||
DisposeVisuals();
|
||||
|
||||
// Do we have a 3D Mode thing?
|
||||
if(modething != null)
|
||||
{
|
||||
|
@ -203,9 +204,8 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
public override void OnUndoEnd()
|
||||
{
|
||||
base.OnUndoEnd();
|
||||
|
||||
allsectors.Clear();
|
||||
allthings.Clear();
|
||||
|
||||
DisposeVisuals();
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
|
@ -236,9 +236,8 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
public override void OnRedoEnd()
|
||||
{
|
||||
base.OnRedoEnd();
|
||||
|
||||
allsectors.Clear();
|
||||
allthings.Clear();
|
||||
|
||||
DisposeVisuals();
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
|
@ -398,10 +397,13 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
{
|
||||
// Create new visual thing
|
||||
vt = CreateVisualThing(t);
|
||||
allthings.Add(t, vt);
|
||||
if(vt != null) allthings.Add(t, vt);
|
||||
}
|
||||
|
||||
visiblethings.Add(vt);
|
||||
if(vt != null)
|
||||
{
|
||||
visiblethings.Add(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,18 +463,21 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
{
|
||||
// Make new visualsector
|
||||
vs = CreateVisualSector(sd.Sector);
|
||||
allsectors.Add(sd.Sector, vs);
|
||||
if(vs != null) allsectors.Add(sd.Sector, vs);
|
||||
}
|
||||
|
||||
// Add to visible sectors if not added yet
|
||||
if(!visiblesectors.ContainsKey(sd.Sector))
|
||||
if(vs != null)
|
||||
{
|
||||
visiblesectors.Add(sd.Sector, vs);
|
||||
visiblegeometry.AddRange(vs.FixedGeometry);
|
||||
// Add to visible sectors if not added yet
|
||||
if(!visiblesectors.ContainsKey(sd.Sector))
|
||||
{
|
||||
visiblesectors.Add(sd.Sector, vs);
|
||||
visiblegeometry.AddRange(vs.FixedGeometry);
|
||||
}
|
||||
|
||||
// Add sidedef geometry
|
||||
visiblegeometry.AddRange(vs.GetSidedefGeometry(sd));
|
||||
}
|
||||
|
||||
// Add sidedef geometry
|
||||
visiblegeometry.AddRange(vs.GetSidedefGeometry(sd));
|
||||
}
|
||||
|
||||
// This returns the camera sector from linedef
|
||||
|
@ -647,7 +652,20 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
#endregion
|
||||
|
||||
#region ================== Processing
|
||||
|
||||
|
||||
// This disposes all visual sectors and things
|
||||
private void DisposeVisuals()
|
||||
{
|
||||
foreach(KeyValuePair<Sector, VisualSector> vs in allsectors)
|
||||
vs.Value.Dispose();
|
||||
|
||||
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
|
||||
vt.Value.Dispose();
|
||||
|
||||
allsectors.Clear();
|
||||
allthings.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implement this to create an instance of your VisualSector implementation.
|
||||
/// </summary>
|
||||
|
@ -744,6 +762,12 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
// Render all visible sectors
|
||||
foreach(VisualGeometry g in visiblegeometry)
|
||||
renderer.AddSectorGeometry(g);
|
||||
|
||||
// Render all visible things
|
||||
foreach(VisualThing t in visiblethings)
|
||||
renderer.AddThingGeometry(t);
|
||||
|
||||
General.WriteLogLine("Things: " + visiblethings.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -118,6 +118,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
this.renderpass = (int)RenderPass.Mask;
|
||||
this.billboard = true;
|
||||
this.orientation = Matrix.Identity;
|
||||
this.position = Matrix.Identity;
|
||||
|
||||
// Register as resource
|
||||
General.Map.Graphics.RegisterResource(this);
|
||||
|
@ -188,9 +189,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
triangles = vertices.Length / 3;
|
||||
updategeo = true;
|
||||
}
|
||||
|
||||
// This updates the visual sector
|
||||
public void Update()
|
||||
|
||||
// This updates the visual thing
|
||||
public virtual void Update()
|
||||
{
|
||||
// Trash geometry buffer
|
||||
if(geobuffer != null) geobuffer.Dispose();
|
||||
|
|
Loading…
Reference in a new issue