mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-24 21:01:33 +00:00
382 lines
10 KiB
C#
382 lines
10 KiB
C#
|
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
|
|
|
/*
|
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
|
* This program is released under GNU General Public License
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#endregion
|
|
|
|
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Drawing;
|
|
using Microsoft.DirectX.Direct3D;
|
|
using System.ComponentModel;
|
|
using Microsoft.DirectX;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.Rendering
|
|
{
|
|
internal class Graphics : IDisposable
|
|
{
|
|
#region ================== Constants
|
|
|
|
// NVPerfHUD device name
|
|
public const string NVPERFHUD_ADAPTER = "NVPerfHUD";
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
// Settings
|
|
private int adapter;
|
|
|
|
// Main objects
|
|
private Control rendertarget;
|
|
private Caps devicecaps;
|
|
private Device device;
|
|
private Renderer2D renderer2d;
|
|
private Renderer3D renderer3d;
|
|
|
|
// Disposing
|
|
private bool isdisposed = false;
|
|
|
|
#endregion
|
|
|
|
#region ================== Properties
|
|
|
|
public Device Device { get { return device; } }
|
|
public bool IsDisposed { get { return isdisposed; } }
|
|
public Renderer2D Renderer2D { get { return renderer2d; } }
|
|
public Renderer3D Renderer3D { get { return renderer3d; } }
|
|
public Control RenderTarget { get { return rendertarget; } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
// Constructor
|
|
public Graphics(Control rendertarget)
|
|
{
|
|
// Set render target
|
|
this.rendertarget = rendertarget;
|
|
|
|
// We have no destructor
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
// Diposer
|
|
public void Dispose()
|
|
{
|
|
// Not already disposed?
|
|
if(!isdisposed)
|
|
{
|
|
// Clean up
|
|
renderer2d.Dispose();
|
|
renderer3d.Dispose();
|
|
device.Dispose();
|
|
rendertarget = null;
|
|
|
|
// Done
|
|
isdisposed = true;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Renderstates
|
|
|
|
// This completes initialization after the device has started or has been reset
|
|
private void SetupSettings()
|
|
{
|
|
// Setup renderstates
|
|
device.SetRenderState(RenderStates.AntialiasedLineEnable, false);
|
|
device.SetRenderState(RenderStates.Ambient, Color.White.ToArgb());
|
|
device.SetRenderState(RenderStates.AmbientMaterialSource, (int)ColorSource.Material);
|
|
device.SetRenderState(RenderStates.ColorVertex, false);
|
|
device.SetRenderState(RenderStates.DiffuseMaterialSource, (int)ColorSource.Color1);
|
|
device.SetRenderState(RenderStates.FillMode, (int)FillMode.Solid);
|
|
device.SetRenderState(RenderStates.FogEnable, false);
|
|
device.SetRenderState(RenderStates.Lighting, false);
|
|
device.SetRenderState(RenderStates.LocalViewer, false);
|
|
device.SetRenderState(RenderStates.NormalizeNormals, false);
|
|
device.SetRenderState(RenderStates.SpecularEnable, false);
|
|
device.SetRenderState(RenderStates.StencilEnable, false);
|
|
device.SetRenderState(RenderStates.PointSpriteEnable, false);
|
|
device.SetRenderState(RenderStates.DitherEnable, true);
|
|
device.SetRenderState(RenderStates.AlphaBlendEnable, false);
|
|
device.SetRenderState(RenderStates.ZEnable, false);
|
|
device.SetRenderState(RenderStates.ZBufferWriteEnable, false);
|
|
device.SetRenderState(RenderStates.Clipping, true);
|
|
device.SetRenderState(RenderStates.CullMode, (int)Cull.None);
|
|
device.VertexFormat = PTVertex.Format;
|
|
|
|
// Sampler settings
|
|
device.SamplerState[0].MagFilter = TextureFilter.Linear;
|
|
device.SamplerState[0].MinFilter = TextureFilter.Linear;
|
|
device.SamplerState[0].MipFilter = TextureFilter.Linear;
|
|
|
|
// Texture addressing
|
|
device.SamplerState[0].AddressU = TextureAddress.Wrap;
|
|
device.SamplerState[0].AddressV = TextureAddress.Wrap;
|
|
device.SamplerState[0].AddressW = TextureAddress.Wrap;
|
|
|
|
// First texture stage
|
|
device.TextureState[0].ColorOperation = TextureOperation.Modulate;
|
|
device.TextureState[0].ColorArgument1 = TextureArgument.Current;
|
|
device.TextureState[0].ColorArgument2 = TextureArgument.TFactor;
|
|
device.TextureState[0].ResultArgument = TextureArgument.Current;
|
|
device.TextureState[0].TextureCoordinateIndex = 0;
|
|
|
|
// No more further stages
|
|
device.TextureState[1].ColorOperation = TextureOperation.Disable;
|
|
|
|
// First alpha stage
|
|
device.TextureState[0].AlphaOperation = TextureOperation.Modulate;
|
|
device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
|
|
device.TextureState[0].AlphaArgument2 = TextureArgument.TFactor;
|
|
|
|
// No more further stages
|
|
device.TextureState[1].AlphaOperation = TextureOperation.Disable;
|
|
|
|
// Setup material
|
|
Material material = new Material();
|
|
material.Ambient = Color.White;
|
|
material.Diffuse = Color.White;
|
|
material.Specular = Color.White;
|
|
device.Material = material;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Initialization
|
|
|
|
// This initializes the graphics
|
|
public bool Initialize()
|
|
{
|
|
PresentParameters displaypp;
|
|
DeviceType devtype;
|
|
|
|
// Use default adapter
|
|
this.adapter = Manager.Adapters.Default.Adapter;
|
|
|
|
// Make present parameters
|
|
displaypp = CreatePresentParameters(adapter);
|
|
|
|
// Determine device type for compatability with NVPerfHUD
|
|
if(Manager.Adapters[adapter].Information.Description.EndsWith(NVPERFHUD_ADAPTER))
|
|
devtype = DeviceType.Reference;
|
|
else
|
|
devtype = DeviceType.Hardware;
|
|
|
|
// Get the device capabilities
|
|
devicecaps = Manager.GetDeviceCaps(adapter, devtype);
|
|
|
|
try
|
|
{
|
|
// Check if this adapter supports TnL
|
|
if(devicecaps.DeviceCaps.SupportsHardwareTransformAndLight)
|
|
{
|
|
// Initialize with hardware TnL
|
|
device = new Device(adapter, devtype, rendertarget,
|
|
CreateFlags.HardwareVertexProcessing, displaypp);
|
|
}
|
|
else
|
|
{
|
|
// Initialize with software TnL
|
|
device = new Device(adapter, devtype, rendertarget,
|
|
CreateFlags.SoftwareVertexProcessing, displaypp);
|
|
}
|
|
}
|
|
catch(Exception)
|
|
{
|
|
// Failed
|
|
MessageBox.Show(General.MainWindow, "Unable to initialize the Direct3D video device. Another application may have taken exclusive mode on this video device.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return false;
|
|
}
|
|
|
|
// Add event to cancel resize event
|
|
device.DeviceResizing += new CancelEventHandler(CancelResize);
|
|
|
|
// Initialize settings
|
|
SetupSettings();
|
|
|
|
// Create renderers
|
|
renderer2d = new Renderer2D(this);
|
|
renderer3d = new Renderer3D(this);
|
|
|
|
// Done
|
|
return true;
|
|
}
|
|
|
|
// This is to disable the automatic resize reset
|
|
private static void CancelResize(object sender, CancelEventArgs e)
|
|
{
|
|
// Cancel resize event
|
|
e.Cancel = true;
|
|
}
|
|
|
|
// This creates present parameters
|
|
private PresentParameters CreatePresentParameters(int adapter)
|
|
{
|
|
PresentParameters displaypp = new PresentParameters();
|
|
DisplayMode currentmode;
|
|
|
|
// Get current display mode
|
|
currentmode = Manager.Adapters[adapter].CurrentDisplayMode;
|
|
|
|
// Make present parameters
|
|
displaypp.Windowed = true;
|
|
displaypp.SwapEffect = SwapEffect.Discard;
|
|
displaypp.BackBufferCount = 1;
|
|
displaypp.BackBufferFormat = currentmode.Format;
|
|
displaypp.BackBufferWidth = rendertarget.ClientSize.Width;
|
|
displaypp.BackBufferHeight = rendertarget.ClientSize.Height;
|
|
displaypp.EnableAutoDepthStencil = true;
|
|
displaypp.AutoDepthStencilFormat = DepthFormat.D16;
|
|
displaypp.MultiSample = MultiSampleType.None;
|
|
displaypp.PresentationInterval = PresentInterval.Immediate;
|
|
|
|
// Return result
|
|
return displaypp;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Resetting
|
|
|
|
// This resets the device and returns true on success
|
|
public bool Reset()
|
|
{
|
|
PresentParameters displaypp;
|
|
|
|
// TODO: Unload all Direct3D resources
|
|
|
|
// Make present parameters
|
|
displaypp = CreatePresentParameters(adapter);
|
|
|
|
try
|
|
{
|
|
// Reset the device
|
|
device.Reset(displaypp);
|
|
}
|
|
catch(Exception)
|
|
{
|
|
// Failed to re-initialize
|
|
return false;
|
|
}
|
|
|
|
// Initialize settings
|
|
SetupSettings();
|
|
|
|
// TODO: Reload all Direct3D resources
|
|
|
|
// Success
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Rendering
|
|
|
|
// This begins a drawing session
|
|
public bool StartRendering()
|
|
{
|
|
int coopresult;
|
|
|
|
// When minimized, do not render anything
|
|
if(General.MainWindow.WindowState != FormWindowState.Minimized)
|
|
{
|
|
// Test the cooperative level
|
|
device.CheckCooperativeLevel(out coopresult);
|
|
|
|
// Check if device must be reset
|
|
if(coopresult == (int)ResultCode.DeviceNotReset)
|
|
{
|
|
// Device is lost and must be reset now
|
|
return Reset();
|
|
}
|
|
// Check if device is lost
|
|
else if(coopresult == (int)ResultCode.DeviceLost)
|
|
{
|
|
// Device is lost and cannot be reset now
|
|
return false;
|
|
}
|
|
|
|
// Clear the screen
|
|
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, 0, 1f, 0);
|
|
|
|
// Ready to render
|
|
device.BeginScene();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// Minimized, you cannot see anything
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// This ends a drawing session
|
|
public void FinishRendering()
|
|
{
|
|
try
|
|
{
|
|
// Done
|
|
device.EndScene();
|
|
|
|
// Display the scene
|
|
device.Present();
|
|
}
|
|
// Errors are not a problem here
|
|
catch(Exception) { }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Tools
|
|
|
|
// Make a color from ARGB
|
|
public static int ARGB(float a, float r, float g, float b)
|
|
{
|
|
return Color.FromArgb((int)(a * 255f), (int)(r * 255f), (int)(g * 255f), (int)(b * 255f)).ToArgb();
|
|
}
|
|
|
|
// Make a color from RGB
|
|
public static int RGB(int r, int g, int b)
|
|
{
|
|
return Color.FromArgb(255, r, g, b).ToArgb();
|
|
}
|
|
|
|
// This makes a Vector3 from Vector3D
|
|
public static Vector3 V3(Vector3D v3d)
|
|
{
|
|
return new Vector3(v3d.x, v3d.y, v3d.z);
|
|
}
|
|
|
|
// This makes a Vector3D from Vector3
|
|
public static Vector3D V3D(Vector3 v3)
|
|
{
|
|
return new Vector3D(v3.X, v3.Y, v3.Z);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|