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:
MaxED 2012-04-18 19:34:11 +00:00
parent 72024341bf
commit 2358b785a1
15 changed files with 290 additions and 312 deletions

View file

@ -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" />

View file

@ -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() {

View file

@ -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();

View file

@ -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();

View file

@ -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) {

View file

@ -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; }
}
}
}

View file

@ -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("")]

View file

@ -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]);
}

View file

@ -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
}

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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;