mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 22:01:45 +00:00
GZDoomBuilder 1.02
All dynamic light types are now rendered correctly. Added Doom-style shading on walls (walls going from west to east are slightly darker than walls going from north to south) Masked surfaces are now correctly lit by dynamic lights. Fixed several bugs in models rendering.
This commit is contained in:
parent
72024341bf
commit
2358b785a1
15 changed files with 290 additions and 312 deletions
|
@ -42,7 +42,8 @@
|
|||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<DocumentationFile>..\..\Build\Builder.xml</DocumentationFile>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<DefineConstants>
|
||||
</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@ -792,7 +793,6 @@
|
|||
<None Include="Resources\Builder16.png" />
|
||||
<None Include="Resources\CLogo.png" />
|
||||
<None Include="Resources\Angle.png" />
|
||||
<Content Include="GZDB2.ico" />
|
||||
<Content Include="Resources\DB2.ico" />
|
||||
<None Include="Resources\GZDB2.ico" />
|
||||
<Content Include="Resources\Light.png" />
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace CodeImp.DoomBuilder.GZBuilder
|
|||
public static int[] GZ_LIGHT_TYPES { get { return gz_lightTypes; } }
|
||||
|
||||
//version
|
||||
public const string Version = "1.01";
|
||||
public const string Version = "1.02";
|
||||
|
||||
//debug form
|
||||
#if DEBUG
|
||||
|
@ -143,6 +143,12 @@ namespace CodeImp.DoomBuilder.GZBuilder
|
|||
#endif
|
||||
}
|
||||
|
||||
public static void TraceInHeader(string message) {
|
||||
#if DEBUG
|
||||
form.Text = message;
|
||||
#endif
|
||||
}
|
||||
|
||||
//actions
|
||||
[BeginAction("gztogglemodels")]
|
||||
private static void toggleModels() {
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
|
|||
public partial class DebugForm : Form
|
||||
{
|
||||
public TextBox TextPannel;
|
||||
public string Title { set{ Text = value; }}
|
||||
|
||||
public DebugForm() {
|
||||
InitializeComponent();
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
this.ClientSize = new System.Drawing.Size(284, 450);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Name = "DebugForm";
|
||||
this.Text = "DebugForm";
|
||||
this.Text = "Console";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Collections.Generic;
|
||||
|
||||
using CodeImp.DoomBuilder;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
|
||||
using SlimDX;
|
||||
|
@ -37,10 +38,8 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
string ext = modelPaths[i].Substring(modelPaths[i].Length - 4);
|
||||
bool loaded = false;
|
||||
if (ext == ".md3") {
|
||||
//loaded = ReadMD3Model(mde, model, mde.Path + "\\" + modelPaths[i], D3DDevice);
|
||||
loaded = ReadMD3Model(ref bbs, mde, model, mde.Path + "\\" + modelPaths[i], D3DDevice);
|
||||
} else if (ext == ".md2") {
|
||||
//loaded = ReadMD2Model(mde, model, mde.Path + "\\" + modelPaths[i], D3DDevice);
|
||||
loaded = ReadMD2Model(ref bbs, mde, model, mde.Path + "\\" + modelPaths[i], D3DDevice);
|
||||
}
|
||||
|
||||
|
@ -88,7 +87,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
s.Position = ofsSurfaces + start;
|
||||
|
||||
List<short> polyIndecesList = new List<short>();
|
||||
List<ModelVertex> vertList = new List<ModelVertex>();
|
||||
List<WorldVertex> vertList = new List<WorldVertex>();
|
||||
|
||||
for (int c = 0; c < numSurfaces; ++c)
|
||||
ReadSurface(ref bbs, br, polyIndecesList, vertList, mde);
|
||||
|
@ -97,7 +96,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
short[] indeces2d_arr = CreateLineListIndeces(polyIndecesList);
|
||||
|
||||
//mesh
|
||||
Mesh mesh = new Mesh(D3DDevice, polyIndecesList.Count / 3, vertList.Count, MeshFlags.IndexBufferManaged | MeshFlags.VertexBufferManaged, ModelVertex.Format);
|
||||
Mesh mesh = new Mesh(D3DDevice, polyIndecesList.Count / 3, vertList.Count, MeshFlags.IndexBufferManaged | MeshFlags.VertexBufferManaged, General.Map.Graphics.Shaders.World3D.VertexElements);
|
||||
|
||||
DataStream stream = mesh.VertexBuffer.Lock(0, 0, LockFlags.None);
|
||||
stream.WriteRange(vertList.ToArray());
|
||||
|
@ -107,6 +106,9 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
stream.WriteRange(polyIndecesList.ToArray());
|
||||
mesh.IndexBuffer.Unlock();
|
||||
|
||||
mesh.OptimizeInPlace(MeshOptimizeFlags.AttributeSort);
|
||||
model.Meshes.Add(mesh);
|
||||
|
||||
//2d data
|
||||
IndexBuffer indeces2d = new IndexBuffer(D3DDevice, 2 * indeces2d_arr.Length, Usage.WriteOnly, Pool.Managed, true);
|
||||
stream = indeces2d.Lock(0, 0, LockFlags.None);
|
||||
|
@ -115,13 +117,11 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
|
||||
model.Indeces2D.Add(indeces2d);
|
||||
model.NumIndeces2D.Add((short)polyIndecesList.Count);
|
||||
|
||||
model.Meshes.Add(mesh);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ReadSurface(ref BoundingBoxSizes bbs, BinaryReader br, List<short> polyIndecesList, List<ModelVertex> vertList, ModelDefEntry mde) {
|
||||
private static void ReadSurface(ref BoundingBoxSizes bbs, BinaryReader br, List<short> polyIndecesList, List<WorldVertex> vertList, ModelDefEntry mde) {
|
||||
var start = br.BaseStream.Position;
|
||||
|
||||
if (ReadString(br, 4) != "IDP3") {
|
||||
|
@ -151,10 +151,10 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
br.BaseStream.Position = start + ofsST;
|
||||
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
ModelVertex v = new ModelVertex();
|
||||
v.Color = 0xffffff;
|
||||
v.Tu = br.ReadSingle();
|
||||
v.Tv = br.ReadSingle();
|
||||
WorldVertex v = new WorldVertex();
|
||||
v.c = 0xffffff;
|
||||
v.u = br.ReadSingle();
|
||||
v.v = br.ReadSingle();
|
||||
|
||||
vertList.Add(v);
|
||||
}
|
||||
|
@ -164,14 +164,13 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
br.BaseStream.Position = start + ofsNormal;
|
||||
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
ModelVertex v = vertList[i];
|
||||
short[] coords = new short[] { br.ReadInt16(), br.ReadInt16(), br.ReadInt16() };
|
||||
WorldVertex v = vertList[i];
|
||||
//short[] coords = new short[] { br.ReadInt16(), br.ReadInt16(), br.ReadInt16() };
|
||||
|
||||
v.Position = new Vector3((float)coords[1] / 64, -(float)coords[0] / 64, (float)coords[2] / 64);
|
||||
v.Position.X *= mde.Scale.Y;
|
||||
v.Position.Y *= mde.Scale.X;
|
||||
v.Position.Z *= mde.Scale.Z;
|
||||
v.Position.Z += mde.zOffset;
|
||||
//v.Position = new Vector3((float)coords[1] / 64, -(float)coords[0] / 64, (float)coords[2] / 64);
|
||||
v.y = -(float)br.ReadInt16() / 64 * mde.Scale.X;
|
||||
v.x = (float)br.ReadInt16() / 64 * mde.Scale.Y;
|
||||
v.z = (float)br.ReadInt16() / 64 * mde.Scale.Z + mde.zOffset;
|
||||
|
||||
//bounding box
|
||||
UpdateBoundingBoxSizes(ref bbs, v);
|
||||
|
@ -179,11 +178,10 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
var lat = br.ReadByte() * (2 * Math.PI) / 255.0;
|
||||
var lng = br.ReadByte() * (2 * Math.PI) / 255.0;
|
||||
|
||||
float nx = (float)(Math.Cos(lng) * Math.Sin(lat));
|
||||
float ny = (float)(Math.Sin(lng) * Math.Sin(lat));
|
||||
float nz = (float)(Math.Cos(lat));
|
||||
v.nx = (float)(Math.Sin(lng) * Math.Sin(lat));
|
||||
v.ny = -(float)(Math.Cos(lng) * Math.Sin(lat));
|
||||
v.nz = (float)(Math.Cos(lat));
|
||||
|
||||
v.Normal = new Vector3(ny, -nx, nz);
|
||||
vertList[i] = v;
|
||||
}
|
||||
|
||||
|
@ -228,7 +226,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
List<short> polyIndecesList = new List<short>();
|
||||
List<short> uvIndecesList = new List<short>();
|
||||
List<Vector2> uvCoordsList = new List<Vector2>();
|
||||
List<ModelVertex> vertList = new List<ModelVertex>();
|
||||
List<WorldVertex> vertList = new List<WorldVertex>();
|
||||
|
||||
//polygons
|
||||
if (s.Position != ofs_tris + start)
|
||||
|
@ -265,34 +263,26 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
//verts
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
//pos
|
||||
ModelVertex v = new ModelVertex();
|
||||
Vector3 vPos = new Vector3(br.ReadByte(), br.ReadByte(), br.ReadByte());
|
||||
WorldVertex v = new WorldVertex();
|
||||
|
||||
vPos.X = scale.X * vPos.X + translate.X;
|
||||
vPos.Y = scale.Y * vPos.Y + translate.Y;
|
||||
vPos.Z = scale.Z * vPos.Z + translate.Z;
|
||||
|
||||
v.Position.X = vPos.X * mde.Scale.X;
|
||||
v.Position.Y = vPos.Y * mde.Scale.Y;
|
||||
v.Position.Z = vPos.Z * mde.Scale.Z;
|
||||
v.Position.Z += mde.zOffset;
|
||||
v.x = ((float)br.ReadByte() * scale.X + translate.X) * mde.Scale.X;
|
||||
v.y = ((float)br.ReadByte() * scale.Y + translate.Y) * mde.Scale.Y;
|
||||
v.z = ((float)br.ReadByte() * scale.Z + translate.Z) * mde.Scale.Z + mde.zOffset;
|
||||
|
||||
vertList.Add(v);
|
||||
//set data for rendering in 2D mode
|
||||
//model.verts2D.Add(new CodeImp.DoomBuilder.Geometry.Vector2D(v.Position.X, -v.Position.Y));
|
||||
|
||||
s.Position += 1; //br.ReadByte(); //vertex normal
|
||||
s.Position += 1; //vertex normal
|
||||
}
|
||||
|
||||
for (int i = 0; i < polyIndecesList.Count; i++) {
|
||||
ModelVertex v = vertList[polyIndecesList[i]];
|
||||
WorldVertex v = vertList[polyIndecesList[i]];
|
||||
|
||||
//bounding box
|
||||
UpdateBoundingBoxSizes(ref bbs, v);
|
||||
|
||||
//uv
|
||||
v.Tu = uvCoordsList[uvIndecesList[i]].X;
|
||||
v.Tv = uvCoordsList[uvIndecesList[i]].Y;
|
||||
v.u = uvCoordsList[uvIndecesList[i]].X;
|
||||
v.v = uvCoordsList[uvIndecesList[i]].Y;
|
||||
|
||||
vertList[polyIndecesList[i]] = v;
|
||||
}
|
||||
|
@ -301,7 +291,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
short[] indeces2d_arr = CreateLineListIndeces(polyIndecesList);
|
||||
|
||||
//mesh
|
||||
Mesh mesh = new Mesh(D3DDevice, polyIndecesList.Count / 3, vertList.Count, MeshFlags.IndexBufferManaged | MeshFlags.VertexBufferManaged, ModelVertex.Format);
|
||||
Mesh mesh = new Mesh(D3DDevice, polyIndecesList.Count / 3, vertList.Count, MeshFlags.IndexBufferManaged | MeshFlags.VertexBufferManaged, General.Map.Graphics.Shaders.World3D.VertexElements);
|
||||
|
||||
DataStream stream = mesh.VertexBuffer.Lock(0, 0, LockFlags.None);
|
||||
stream.WriteRange(vertList.ToArray());
|
||||
|
@ -311,6 +301,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
stream.WriteRange(polyIndecesList.ToArray());
|
||||
mesh.IndexBuffer.Unlock();
|
||||
|
||||
mesh.OptimizeInPlace(MeshOptimizeFlags.AttributeSort);
|
||||
model.Meshes.Add(mesh);
|
||||
|
||||
//2d data
|
||||
|
@ -363,21 +354,21 @@ namespace ColladaDotNet.Pipeline.MD3 {
|
|||
return new Vector3[] { v0, v1, v2, v3, v4, v5, v6, v7, v8 };
|
||||
}
|
||||
|
||||
private static void UpdateBoundingBoxSizes(ref BoundingBoxSizes bbs, ModelVertex v) {
|
||||
if (v.Position.X < bbs.MinX)
|
||||
bbs.MinX = (short)v.Position.X;
|
||||
else if (v.Position.X > bbs.MaxX)
|
||||
bbs.MaxX = (short)v.Position.X;
|
||||
private static void UpdateBoundingBoxSizes(ref BoundingBoxSizes bbs, WorldVertex v) {
|
||||
if (v.x < bbs.MinX)
|
||||
bbs.MinX = (short)v.x;
|
||||
else if (v.x > bbs.MaxX)
|
||||
bbs.MaxX = (short)v.x;
|
||||
|
||||
if (v.Position.Z < bbs.MinZ)
|
||||
bbs.MinZ = (short)v.Position.Z;
|
||||
else if (v.Position.Z > bbs.MaxZ)
|
||||
bbs.MaxZ = (short)v.Position.Z;
|
||||
if (v.z < bbs.MinZ)
|
||||
bbs.MinZ = (short)v.z;
|
||||
else if (v.z > bbs.MaxZ)
|
||||
bbs.MaxZ = (short)v.z;
|
||||
|
||||
if (v.Position.Y < bbs.MinY)
|
||||
bbs.MinY = (short)v.Position.Y;
|
||||
else if (v.Position.Y > bbs.MaxY)
|
||||
bbs.MaxY = (short)v.Position.Y;
|
||||
if (v.y < bbs.MinY)
|
||||
bbs.MinY = (short)v.y;
|
||||
else if (v.y > bbs.MaxY)
|
||||
bbs.MaxY = (short)v.y;
|
||||
}
|
||||
|
||||
private static string ReadString(BinaryReader br, int len) {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using SlimDX;
|
||||
using SlimDX.Direct3D9;
|
||||
|
||||
namespace ColladaDotNet.Pipeline.MD3 {
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ModelVertex
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Vector3 Normal;
|
||||
public int Color;
|
||||
public float Tu;
|
||||
public float Tv;
|
||||
|
||||
public static int SizeBytes {
|
||||
get { return Marshal.SizeOf(typeof(ModelVertex)); }
|
||||
}
|
||||
|
||||
public static VertexFormat Format {
|
||||
get { return VertexFormat.Position | VertexFormat.Diffuse | VertexFormat.Texture1 | VertexFormat.Normal; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
|||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Doom Builder")]
|
||||
[assembly: AssemblyTitle("GZDoomBuilder")]
|
||||
[assembly: AssemblyDescription("Doom, Heretic and Hexen map editor")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("CodeImp")]
|
||||
[assembly: AssemblyProduct("Doom Builder")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2007")]
|
||||
[assembly: AssemblyCompany("CodeImp, MaxED")]
|
||||
[assembly: AssemblyProduct("GZDoomBuilder")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2007, 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
|
|
@ -1157,7 +1157,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.Things2D.ApplySettings();
|
||||
|
||||
// Draw
|
||||
graphics.Device.SetStreamSource(0, model.Meshes[i].VertexBuffer, 0, ModelVertex.SizeBytes);
|
||||
graphics.Device.SetStreamSource(0, model.Meshes[i].VertexBuffer, 0, WorldVertex.Stride);
|
||||
graphics.Device.Indices = model.Indeces2D[i];
|
||||
graphics.Device.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, model.Meshes[i].VertexCount, 0, model.NumIndeces2D[i]);
|
||||
}
|
||||
|
|
|
@ -75,13 +75,15 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
// Thing cage
|
||||
//private VertexBuffer thingcage;
|
||||
private bool renderthingcages;
|
||||
//mxd
|
||||
private ThingBoundingBox bbox;
|
||||
private List<VisualThing> thingsWithLight;
|
||||
private int[] lightOffsets;
|
||||
private List<VisualGeometry> litGeometry;
|
||||
private Dictionary<ModelDefEntry, List<VisualThing>> thingsWithModel;
|
||||
private bool renderthingcages;
|
||||
//mxd
|
||||
private ThingBoundingBox bbox;
|
||||
private List<VisualThing> thingsWithLight;
|
||||
private int[] lightOffsets;
|
||||
private Dictionary<Texture, List<VisualGeometry>> litGeometry;
|
||||
private Dictionary<ModelDefEntry, List<VisualThing>> thingsWithModel;
|
||||
//dbg
|
||||
int geoSkipped = 0;
|
||||
|
||||
// Crosshair
|
||||
private FlatVertex[] crosshairverts;
|
||||
|
@ -506,6 +508,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd
|
||||
if (General.Settings.GZDrawLights) {
|
||||
thingsWithLight = new List<VisualThing>();
|
||||
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.ClearTrace();
|
||||
//geoSkipped = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,10 +521,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd. sort lights
|
||||
if (General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0)
|
||||
updateLights();
|
||||
|
||||
//mxd. dbg
|
||||
//GZBuilder.GZGeneral.ClearTrace();
|
||||
//GZBuilder.GZGeneral.Trace("CamPos: " + General.Map.VisualCamera.Position.ToString());
|
||||
|
||||
// Initial renderstates
|
||||
graphics.Device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
|
||||
|
@ -530,15 +532,15 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.World3D.Begin();
|
||||
|
||||
//mxd
|
||||
litGeometry = new List<VisualGeometry>();
|
||||
litGeometry = new Dictionary<Texture, List<VisualGeometry>>();
|
||||
|
||||
// SOLID PASS
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
RenderSinglePass((int)RenderPass.Solid);
|
||||
|
||||
//mxd
|
||||
litGeometry = new List<VisualGeometry>();
|
||||
//mxd. Render models
|
||||
RenderModels();
|
||||
|
||||
// MASK PASS
|
||||
world = Matrix.Identity;
|
||||
|
@ -546,9 +548,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
|
||||
RenderSinglePass((int)RenderPass.Mask);
|
||||
|
||||
//mxd
|
||||
litGeometry = new List<VisualGeometry>();
|
||||
|
||||
// ALPHA PASS
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
|
@ -559,33 +558,18 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
|
||||
RenderSinglePass((int)RenderPass.Alpha);
|
||||
|
||||
//mxd. Something in model rendering process screws Additive pass badly. so I moved it here to avoid this.
|
||||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.One);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.Zero);
|
||||
RenderModels();
|
||||
//graphics.Device.SetRenderState(RenderState.CullMode, Cull.Counterclockwise);
|
||||
graphics.Device.SetRenderState(RenderState.ZEnable, true);
|
||||
graphics.Device.SetRenderState(RenderState.ZWriteEnable, false);
|
||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
|
||||
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);
|
||||
|
||||
|
||||
// THINGS
|
||||
if(renderthingcages) RenderThingCages();
|
||||
|
||||
//mxd
|
||||
litGeometry = new List<VisualGeometry>();
|
||||
|
||||
// ADDITIVE PASS
|
||||
world = Matrix.Identity;
|
||||
ApplyMatrices3D();
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.One);
|
||||
RenderSinglePass((int)RenderPass.Additive);
|
||||
|
||||
|
||||
//mxd. LIGHT PASS
|
||||
if (General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0 && litGeometry.Count > 0)
|
||||
RenderLights(litGeometry, thingsWithLight);
|
||||
|
||||
// Remove references
|
||||
graphics.Shaders.World3D.Texture1 = null;
|
||||
|
@ -593,6 +577,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Done
|
||||
graphics.Shaders.World3D.End();
|
||||
geometry = null;
|
||||
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.TraceLine("Skipped "+geoSkipped+" geometries");
|
||||
//GZBuilder.GZGeneral.TraceInHeader("FPS:" + calculateFrameRate());
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -631,69 +619,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// This renders all thing cages
|
||||
/*private void RenderThingCages()
|
||||
{
|
||||
int currentshaderpass = shaderpass;
|
||||
int highshaderpass = shaderpass + 2;
|
||||
|
||||
// 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(shaderpass);
|
||||
foreach(VisualThing t in thingsbydistance)
|
||||
{
|
||||
// Determine the shader pass we want to use for this object
|
||||
int wantedshaderpass = (((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
// Switch shader pass?
|
||||
if(currentshaderpass != wantedshaderpass)
|
||||
{
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
graphics.Shaders.World3D.BeginPass(wantedshaderpass);
|
||||
currentshaderpass = wantedshaderpass;
|
||||
}
|
||||
|
||||
// Setup matrix
|
||||
world = Matrix.Multiply(t.CageScales, t.Position);
|
||||
ApplyMatrices3D();
|
||||
|
||||
// Setup color
|
||||
if(currentshaderpass == highshaderpass)
|
||||
{
|
||||
Color4 highcolor = CalculateHighlightColor((t == highlighted) && showhighlight, t.Selected && showselection);
|
||||
graphics.Shaders.World3D.SetHighlightColor(highcolor.ToArgb());
|
||||
highcolor.Alpha = 1.0f;
|
||||
graphics.Shaders.World3D.SetModulateColor(highcolor.ToArgb());
|
||||
graphics.Device.SetRenderState(RenderState.TextureFactor, highcolor.ToArgb());
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}*/
|
||||
|
||||
//mxd. By adding model rendering section I somehow screwed DoomBuilder's ThingCages rendering process.
|
||||
//I never particularly liked old ThingCages, so I wrote this instead of fixing them.
|
||||
//mxd.
|
||||
//I never particularly liked old ThingCages, so I wrote this instead.
|
||||
//It should render faster and it has fancy arrow! :)
|
||||
private void RenderThingCages() {
|
||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true);
|
||||
|
@ -702,6 +629,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.SourceAlpha);
|
||||
|
||||
//mxd. Doesn't look nearly as good as I expected :(
|
||||
//graphics.Device.SetRenderState(RenderState.AntialiasedLineEnable, General.Settings.QualityDisplay);
|
||||
|
||||
graphics.Shaders.World3D.BeginPass(8);
|
||||
|
@ -810,9 +738,12 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Determine the shader pass we want to use for this object
|
||||
int wantedshaderpass = (((g == highlighted) && showhighlight) || (g.Selected && showselection)) ? highshaderpass : shaderpass;
|
||||
|
||||
//mxd
|
||||
if (General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0)
|
||||
litGeometry.Add(g);
|
||||
//mxd. Seems that translucent lines aren't affected by dynamic lights in GZDoom
|
||||
if (g.RenderPass != RenderPass.Alpha && General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0) {
|
||||
if (!litGeometry.ContainsKey(curtexture.Texture))
|
||||
litGeometry[curtexture.Texture] = new List<VisualGeometry>();
|
||||
litGeometry[curtexture.Texture].Add(g);
|
||||
}
|
||||
|
||||
// Switch shader pass?
|
||||
if(currentshaderpass != wantedshaderpass)
|
||||
|
@ -840,84 +771,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Dynamic lights pass!
|
||||
if (General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0 && litGeometry.Count > 0) {
|
||||
graphics.Shaders.World3D.World = world;
|
||||
if (currentshaderpass != 9) {
|
||||
currentshaderpass = 9;
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
graphics.Shaders.World3D.BeginPass(currentshaderpass);
|
||||
}
|
||||
|
||||
int i, count;
|
||||
Vector4 lpr;
|
||||
|
||||
//dbg
|
||||
//int gcount = 0;
|
||||
|
||||
foreach (VisualGeometry g in litGeometry) {
|
||||
i = 0;
|
||||
count = 0;
|
||||
|
||||
//dbg
|
||||
//gcount++;
|
||||
|
||||
graphics.Device.SetStreamSource(0, g.Sector.GeometryBuffer, 0, WorldVertex.Stride);
|
||||
|
||||
//normal lights
|
||||
count = lightOffsets[0];
|
||||
if (lightOffsets[0] > 0) {
|
||||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.BlendFactor);
|
||||
for (i = 0; i < count; i++) {
|
||||
lpr = thingsWithLight[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
graphics.Shaders.World3D.LightColor = thingsWithLight[i].LightColor;
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = thingsWithLight[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
|
||||
//additive lights.
|
||||
if (lightOffsets[1] > 0) {
|
||||
count += lightOffsets[1];
|
||||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.One);
|
||||
for (i = lightOffsets[0]; i < count; i++) {
|
||||
lpr = thingsWithLight[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
graphics.Shaders.World3D.LightColor = thingsWithLight[i].LightColor;
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = thingsWithLight[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
|
||||
//negative lights
|
||||
if (lightOffsets[2] > 0) {
|
||||
count += lightOffsets[2];
|
||||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.InverseBlendFactor);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceColor);
|
||||
for (i = lightOffsets[0] + lightOffsets[1]; i < count; i++) {
|
||||
lpr = thingsWithLight[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
graphics.Shaders.World3D.LightColor = thingsWithLight[i].LightColor;
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = thingsWithLight[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false); //disable AlphaBlending which is turned on in shader
|
||||
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.Trace("Pass: " + pass + "; Lit " + gcount + " geometries; Lights: [" + lightOffsets[0] + ";" + lightOffsets[1] + ";" + lightOffsets[2] + "]" + Environment.NewLine + "Models count: " + thingsWithModel.Count + Environment.NewLine);
|
||||
}
|
||||
|
||||
// Get things for this pass
|
||||
Dictionary<ImageData, List<VisualThing>> thingspass = things[pass];
|
||||
if(thingspass.Count > 0)
|
||||
|
@ -966,16 +819,15 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd. if current thing is light - set it's color to light color
|
||||
if (t.LightType != -1) {
|
||||
wantedshaderpass += 4; //render using one of passes, which uses World3D.VertexColor
|
||||
Color4 c = t.LightColor;
|
||||
/*Color4 c = t.LightColor;
|
||||
if (t.LightRenderStyle == (int)GZDoomLightRenderStyle.NEGATIVE) {
|
||||
c.Red = 1.0f - t.LightColor.Blue;
|
||||
c.Green = 1.0f - t.LightColor.Green;
|
||||
c.Blue = 1.0f - t.LightColor.Red;
|
||||
}
|
||||
graphics.Shaders.World3D.VertexColor = c;
|
||||
} */
|
||||
graphics.Shaders.World3D.VertexColor = t.LightColor;
|
||||
//mxd. check if Thing is affected by dynamic lights and set color accordingly
|
||||
}else if (General.Settings.GZDrawLights && !fullbrightness && thingsWithLight.Count > 0) {
|
||||
//Color4 litColor = getLitColor(new Vector3(t.Thing.Position.x, t.Thing.Position.y, t.Thing.Position.z + t.Thing.Sector.FloorHeight));
|
||||
Color4 litColor = getLitColor(t.PositionV3);
|
||||
if (litColor.ToArgb() != 0) {
|
||||
wantedshaderpass += 4; //render using one of passes, which uses World3D.VertexColor
|
||||
|
@ -1025,6 +877,92 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.World3D.EndPass();
|
||||
}
|
||||
|
||||
//mxd. Dynamic lights pass!
|
||||
private void RenderLights(Dictionary<Texture, List<VisualGeometry>> geometry_to_lit, List<VisualThing> lights) {
|
||||
graphics.Shaders.World3D.World = world;
|
||||
graphics.Shaders.World3D.BeginPass(9);
|
||||
|
||||
int i, count;
|
||||
Vector4 lpr;
|
||||
|
||||
//dbg
|
||||
//int gcount = 0;
|
||||
|
||||
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.One);
|
||||
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.BlendFactor);
|
||||
|
||||
foreach (KeyValuePair<Texture, List<VisualGeometry>> group in geometry_to_lit) {
|
||||
graphics.Shaders.World3D.Texture1 = group.Key;
|
||||
|
||||
foreach (VisualGeometry g in group.Value) {
|
||||
i = 0;
|
||||
count = 0;
|
||||
|
||||
//dbg
|
||||
//gcount++;
|
||||
|
||||
graphics.Device.SetStreamSource(0, g.Sector.GeometryBuffer, 0, WorldVertex.Stride);
|
||||
|
||||
//normal lights
|
||||
count = lightOffsets[0];
|
||||
if (lightOffsets[0] > 0) {
|
||||
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
lpr = lights[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
|
||||
//additive lights.
|
||||
if (lightOffsets[1] > 0) {
|
||||
count += lightOffsets[1];
|
||||
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
|
||||
|
||||
for (i = lightOffsets[0]; i < count; i++) {
|
||||
lpr = lights[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
|
||||
//negative lights
|
||||
if (lightOffsets[2] > 0) {
|
||||
count += lightOffsets[2];
|
||||
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.ReverseSubtract);
|
||||
|
||||
for (i = lightOffsets[0] + lightOffsets[1]; i < count; i++) {
|
||||
lpr = lights[i].LightPositionAndRadius;
|
||||
if (lpr.W == 0)
|
||||
continue;
|
||||
Color4 lc = lights[i].LightColor;
|
||||
graphics.Shaders.World3D.LightColor = new Color4(1.0f, (lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2);
|
||||
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
|
||||
|
||||
//graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, alphaBlendEnabled); //disable AlphaBlending which is turned on in shader
|
||||
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.TraceLine("Lit " + gcount + " geometries; Lights: [" + lightOffsets[0] + ";" + lightOffsets[1] + ";" + lightOffsets[2] + "]" + Environment.NewLine + "Models count: " + thingsWithModel.Count);
|
||||
}
|
||||
|
||||
//mxd. render models
|
||||
private void RenderModels() {
|
||||
int shaderpass = 4;
|
||||
|
@ -1047,34 +985,34 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
graphics.Shaders.World3D.VertexColor = vertexColor;
|
||||
}
|
||||
|
||||
// Determine the shader pass we want to use for this object
|
||||
int wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.Trace("Rendering mesh with "+wantedshaderpass+" pass."+Environment.NewLine);
|
||||
|
||||
// Switch shader pass?
|
||||
if (currentshaderpass != wantedshaderpass) {
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
graphics.Shaders.World3D.BeginPass(wantedshaderpass);
|
||||
currentshaderpass = wantedshaderpass;
|
||||
}
|
||||
|
||||
// Set the colors to use
|
||||
if (!graphics.Shaders.Enabled) {
|
||||
graphics.Device.SetTexture(2, (t.Selected && showselection) ? selectionimage.Texture : null);
|
||||
graphics.Device.SetTexture(3, ((t == highlighted) && showhighlight) ? highlightimage.Texture : null);
|
||||
} else {
|
||||
graphics.Shaders.World3D.SetHighlightColor(CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)).ToArgb());
|
||||
}
|
||||
|
||||
// Create the matrix for positioning / rotation
|
||||
world = Matrix.Multiply(t.Orientation, Matrix.RotationZ(t.Thing.Angle));
|
||||
world = Matrix.Multiply(world, t.Position);
|
||||
ApplyMatrices3D();
|
||||
|
||||
for (int i = 0; i < group.Key.Model.NUM_MESHES; i++) {
|
||||
if (!graphics.Shaders.Enabled) graphics.Device.SetTexture(0, group.Key.Model.Textures[i]);
|
||||
graphics.Shaders.World3D.Texture1 = group.Key.Model.Textures[i];
|
||||
|
||||
// Determine the shader pass we want to use for this object
|
||||
int wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.Trace("Rendering mesh with "+wantedshaderpass+" pass."+Environment.NewLine);
|
||||
|
||||
// Switch shader pass?
|
||||
if (currentshaderpass != wantedshaderpass) {
|
||||
graphics.Shaders.World3D.EndPass();
|
||||
graphics.Shaders.World3D.BeginPass(wantedshaderpass);
|
||||
currentshaderpass = wantedshaderpass;
|
||||
}
|
||||
|
||||
// Set the colors to use
|
||||
if (!graphics.Shaders.Enabled) {
|
||||
graphics.Device.SetTexture(2, (t.Selected && showselection) ? selectionimage.Texture : null);
|
||||
graphics.Device.SetTexture(3, ((t == highlighted) && showhighlight) ? highlightimage.Texture : null);
|
||||
} else {
|
||||
graphics.Shaders.World3D.SetHighlightColor(CalculateHighlightColor((t == highlighted) && showhighlight, (t.Selected && showselection)).ToArgb());
|
||||
}
|
||||
|
||||
// Create the matrix for positioning / rotation
|
||||
world = Matrix.Multiply(t.Orientation, Matrix.RotationZ(t.Thing.Angle));
|
||||
world = Matrix.Multiply(world, t.Position);
|
||||
ApplyMatrices3D();
|
||||
graphics.Shaders.World3D.ApplySettings();
|
||||
|
||||
// Render!
|
||||
|
@ -1087,7 +1025,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
//mxd. This gets color from dynamic lights based on distance to thing.
|
||||
//WARNING: thing position must be in absolute cordinates
|
||||
//(thing.Position.Z value is actually relative to floor of the sector the thing is in)
|
||||
//(thing.Position.Z value is relative to floor of the sector the thing is in)
|
||||
//so use visualThing.PositionV3 instead
|
||||
private Color4 getLitColor(Vector3 thingPosition) {
|
||||
Color4 litColor = new Color4();
|
||||
|
@ -1137,6 +1075,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
highlighted = obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This collects a visual sector's geometry for rendering
|
||||
public void AddSectorGeometry(VisualGeometry g)
|
||||
|
@ -1144,7 +1084,15 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Must have a texture and vertices
|
||||
if((g.Texture != null) && (g.Triangles > 0))
|
||||
{
|
||||
// Texture group not yet collected?
|
||||
//mxd
|
||||
/*double angle = Math.Acos(Vector3D.DotProduct(g.Normal, Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ).GetNormal()));
|
||||
//GZBuilder.GZGeneral.TraceLine("angle=" + angle);
|
||||
if (angle < 0.78f) { //if angle between geometry normal and camera normal is greater than 135 deg.
|
||||
geoSkipped++;
|
||||
return;
|
||||
}*/
|
||||
|
||||
// Texture group not yet collected?
|
||||
if(!geometry[g.RenderPassInt].ContainsKey(g.Texture))
|
||||
{
|
||||
// Create texture group
|
||||
|
@ -1279,6 +1227,19 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
crosshairbusy = busy;
|
||||
}
|
||||
|
||||
//dbg
|
||||
private int lastTick, lastFrameRate, frameRate;
|
||||
|
||||
private int calculateFrameRate() {
|
||||
if (System.Environment.TickCount - lastTick >= 1000) {
|
||||
lastFrameRate = frameRate;
|
||||
frameRate = 0;
|
||||
lastTick = System.Environment.TickCount;
|
||||
}
|
||||
frameRate++;
|
||||
return lastFrameRate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
private EffectHandle lightPositionAndRadiusHandle;
|
||||
private EffectHandle lightColorHandle;
|
||||
private EffectHandle worldHandle;
|
||||
//used in ModelReader
|
||||
private VertexElement[] vertexElements;
|
||||
|
||||
|
||||
#endregion
|
||||
|
@ -70,6 +72,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
public Color4 LightColor { set { if (manager.Enabled) effect.SetValue<Color4>(lightColorHandle, value); } }
|
||||
public Vector4 LightPositionAndRadius { set { if (manager.Enabled) effect.SetValue(lightPositionAndRadiusHandle, value); } }
|
||||
public Matrix World { set { if (manager.Enabled) effect.SetValue<Matrix>(worldHandle, value); } }
|
||||
public VertexElement[] VertexElements { get { return vertexElements; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -102,7 +105,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
|
||||
// Initialize world vertex declaration
|
||||
VertexElement[] elements = new VertexElement[]
|
||||
vertexElements = new VertexElement[]
|
||||
{
|
||||
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
|
||||
new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
|
||||
|
@ -111,7 +114,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
new VertexElement(0, 24, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
|
||||
VertexElement.VertexDeclarationEnd
|
||||
};
|
||||
vertexdecl = new VertexDeclaration(General.Map.Graphics.Device, elements);
|
||||
vertexdecl = new VertexDeclaration(General.Map.Graphics.Device, vertexElements);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 173 KiB |
Binary file not shown.
|
@ -153,14 +153,33 @@ float4 ps_constant_color(PixelData pd) : COLOR {
|
|||
//mxd. dynamic light pixel shader pass, dood!
|
||||
float4 ps_lightpass(LitPixelData pd) : COLOR {
|
||||
//is face facing away from light source?
|
||||
if(dot(pd.normal, (lightPosAndRadius.xyz - pd.pos_w)) < 0) // (lightPosAndRadius.xyz - pd.pos_w) == direction from light to current pixel
|
||||
return float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
//return lightColorMod;
|
||||
if(dot(pd.normal, (lightPosAndRadius.xyz - pd.pos_w)) <= 0) // (lightPosAndRadius.xyz - pd.pos_w) == direction from light to current pixel
|
||||
clip(-1);
|
||||
|
||||
//is pixel in light range?
|
||||
float dist = distance(pd.pos_w, lightPosAndRadius.xyz);
|
||||
if(dist > lightPosAndRadius.w)
|
||||
clip(-1);
|
||||
|
||||
//is pixel tranparent?
|
||||
float4 tcolor = tex2D(texturesamp, pd.uv);
|
||||
if(tcolor.a == 0.0f)
|
||||
clip(-1);
|
||||
|
||||
//if not - calculate color at current pixel
|
||||
float4 lightColorMod = float4(0.0f, 0.0f, 0.0f, lightColor.a);
|
||||
lightColorMod.rgb = lightColor.rgb * max(lightPosAndRadius.w - distance(pd.pos_w, lightPosAndRadius.xyz), 0.0f) / lightPosAndRadius.w;
|
||||
return lightColorMod;
|
||||
//if it is - calculate color at current pixel
|
||||
float4 lightColorMod = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
lightColorMod.rgb = lightColor.rgb * max(lightPosAndRadius.w - dist, 0.0f) / lightPosAndRadius.w;
|
||||
if(lightColorMod.r > 0.0f || lightColorMod.g > 0.0f || lightColorMod.b > 0.0f){
|
||||
if(lightColor.a == 1.0f){ //Normal or negative light
|
||||
lightColorMod.rgb *= 0.9f;
|
||||
return tcolor * lightColorMod;
|
||||
}
|
||||
lightColorMod.rgb *= 0.25f;
|
||||
return lightColorMod; //Additive light
|
||||
}
|
||||
clip(-1);
|
||||
return lightColorMod; //should never get here
|
||||
}
|
||||
|
||||
// Technique for shader model 2.0
|
||||
|
|
|
@ -78,6 +78,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
// Sector buffer info
|
||||
private int vertexoffset;
|
||||
|
||||
//mxd
|
||||
//private Vector3D normal;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -90,6 +93,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
internal int RenderPassInt { get { return renderpass; } }
|
||||
internal Color4 ModColor4 { get { return modcolor4; } }
|
||||
|
||||
//mxd
|
||||
//internal Vector3D Normal { get { return normal; } }
|
||||
|
||||
/// <summary>
|
||||
/// Render pass in which this geometry must be rendered. Default is Solid.
|
||||
/// </summary>
|
||||
|
@ -155,12 +161,13 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
vertices = new WorldVertex[verts.Count];
|
||||
verts.CopyTo(vertices, 0);
|
||||
triangles = vertices.Length / 3;
|
||||
CalculateNormals();
|
||||
//mxd
|
||||
CalculateNormalsAndShading();
|
||||
if(sector != null) sector.NeedsUpdateGeo = true;
|
||||
}
|
||||
|
||||
//mxd. Taken from OpenGl wiki
|
||||
protected void CalculateNormals() {
|
||||
protected void CalculateNormalsAndShading() {
|
||||
int startIndex;
|
||||
Vector3 U, V;
|
||||
for (int i = 0; i < triangles; i++) {
|
||||
|
@ -176,10 +183,25 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
p1.ny = p2.ny = p3.ny = -(U.Z * V.X - U.X * V.Z);
|
||||
p1.nz = p2.nz = p3.nz = -(U.X * V.Y - U.Y * V.X);
|
||||
|
||||
//doom-style walls shading
|
||||
//not very apropriate place to put this, but most convinient :)
|
||||
if (sidedef != null) {
|
||||
byte valMod = (byte)(Math.Abs((float)Math.Sin(sidedef.Angle)) * 0.07f * 255);
|
||||
PixelColor modColor = new PixelColor(255, valMod, valMod, valMod);
|
||||
PixelColor pc = PixelColor.FromInt(p1.c);
|
||||
|
||||
if (pc.r < modColor.r) modColor.r = pc.r;
|
||||
if (pc.g < modColor.g) modColor.g = pc.g;
|
||||
if (pc.b < modColor.b) modColor.b = pc.b;
|
||||
|
||||
p1.c = p2.c = p3.c -= modColor.ToColorRef();
|
||||
}
|
||||
|
||||
vertices[startIndex] = p1;
|
||||
vertices[startIndex + 1] = p2;
|
||||
vertices[startIndex + 2] = p3;
|
||||
}
|
||||
// normal = new Vector3D(vertices[0].nx, vertices[0].ny, vertices[0].nz).GetNormal();
|
||||
}
|
||||
|
||||
// This compares for sorting by sector
|
||||
|
|
|
@ -358,15 +358,16 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) {
|
||||
n = 0;
|
||||
lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL;
|
||||
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
|
||||
//lightColor.Alpha used in shader to perform some cations based on light type
|
||||
lightColor = new Color4(1.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
|
||||
} else if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) {
|
||||
n = 10;
|
||||
lightRenderStyle = (int)GZDoomLightRenderStyle.ADDITIVE;
|
||||
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
|
||||
lightColor = new Color4(0.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
|
||||
} else {
|
||||
n = 20;
|
||||
lightRenderStyle = (int)GZDoomLightRenderStyle.NEGATIVE;
|
||||
lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[2] / 255, (float)thing.Args[1] / 255, (float)thing.Args[0] / 255);
|
||||
lightColor = new Color4(1.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
|
||||
}
|
||||
lightType = thing.Type - 9800 - n;
|
||||
|
||||
|
|
Loading…
Reference in a new issue