Permalink
Browse files

Simplify render pipeline

  • Loading branch information...
tgjones committed Dec 26, 2017
1 parent b7dc4ea commit 61994bee78f963a40eb4fea2c86c8113ceef78ab
Showing with 491 additions and 549 deletions.
  1. +11 −6 src/OpenSage.DataViewer/UI/Viewers/Ini/ObjectDefinitionView.cs
  2. +0 −11 src/OpenSage.Game/Content/MapLoader.cs
  3. +10 −14 src/OpenSage.Game/Content/ModelLoader.cs
  4. +1 −1 src/OpenSage.Game/Entity.cs
  5. +3 −0 src/OpenSage.Game/GameSystem.cs
  6. +13 −0 src/OpenSage.Game/Graphics/Effects/Effect.cs
  7. +11 −1 src/OpenSage.Game/Graphics/Effects/EffectMaterial.cs
  8. +12 −0 src/OpenSage.Game/Graphics/Effects/MeshMaterial.cs
  9. +10 −1 src/OpenSage.Game/Graphics/Effects/SpriteMaterial.cs
  10. +11 −19 src/OpenSage.Game/Graphics/GraphicsSystem.cs
  11. +28 −72 src/OpenSage.Game/Graphics/ModelMesh.cs
  12. +1 −6 src/OpenSage.Game/Graphics/ModelMeshPart.cs
  13. +11 −19 src/OpenSage.Game/Graphics/ParticleSystems/ParticleSystem.cs
  14. +9 −0 src/OpenSage.Game/Graphics/ParticleSystems/ParticleSystemManager.cs
  15. +3 −1 src/OpenSage.Game/Graphics/RenderableComponent.cs
  16. +7 −8 src/OpenSage.Game/Graphics/Rendering/Culler.cs
  17. +84 −21 src/OpenSage.Game/Graphics/Rendering/RenderItem.cs
  18. +67 −96 src/OpenSage.Game/Graphics/Rendering/RenderList.cs
  19. +77 −65 src/OpenSage.Game/Graphics/Rendering/RenderPipeline.cs
  20. +0 −135 src/OpenSage.Game/Graphics/SpriteBatch.cs
  21. +30 −0 src/OpenSage.Game/Graphics/SpriteVertex.cs
  22. +46 −6 src/OpenSage.Game/Gui/Elements/UIElement.cs
  23. +2 −15 src/OpenSage.Game/Gui/GuiComponent.cs
  24. +22 −25 src/OpenSage.Game/Gui/GuiSystem.cs
  25. +5 −5 src/OpenSage.Game/Mathematics/BoundingFrustum.cs
  26. +5 −0 src/OpenSage.Game/Terrain/TerrainMaterial.cs
  27. +9 −19 src/OpenSage.Game/Terrain/TerrainPatchComponent.cs
  28. +3 −3 src/OpenSage.LowLevel/Graphics3D/CommandEncoder.D3D11.cs
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using System.Numerics;
using Eto.Forms;
using OpenSage.Data.Ini;
@@ -31,7 +30,11 @@ public ObjectDefinitionView(Game game, ObjectDefinition objectDefinition)
_listBox = new ListBox();
_listBox.Width = 200;
_listBox.ItemTextBinding = Binding.Property((BitArray<ModelConditionFlag> x) => x.DisplayName);
_listBox.SelectedValueChanged += OnSelectedValueChanged;
_listBox.SelectedValueChanged += (sender, e) =>
{
var modelConditionState = (BitArray<ModelConditionFlag>) _listBox.SelectedValue;
_objectComponent.SetModelConditionFlags(modelConditionState);
};
_listBox.DataStore = _objectComponent.ModelConditionStates.ToList();
_listBox.SelectedIndex = 0;

@@ -43,10 +46,12 @@ public ObjectDefinitionView(Game game, ObjectDefinition objectDefinition)
};
}

private void OnSelectedValueChanged(object sender, EventArgs e)
protected override void Dispose(bool disposing)
{
var modelConditionState = (BitArray<ModelConditionFlag>) _listBox.SelectedValue;
_objectComponent.SetModelConditionFlags(modelConditionState);
Panel1.Dispose();
Panel2.Dispose();

base.Dispose(disposing);
}
}
}
@@ -44,12 +44,6 @@ protected override Scene LoadEntry(FileSystemEntry entry, ContentManager content
HeightMap = heightMap
});

var pipelineStateSolid = new EffectPipelineState(
RasterizerStateDescription.CullBackSolid,
DepthStencilStateDescription.Default,
BlendStateDescription.Opaque)
.GetHandle();

var indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(contentManager.GraphicsDevice));

var tileDataTexture = AddDisposable(CreateTileDataTexture(
@@ -85,7 +79,6 @@ protected override Scene LoadEntry(FileSystemEntry entry, ContentManager content
heightMap,
mapFile.BlendTileData,
terrainMaterial,
pipelineStateSolid,
indexBufferCache);

var objectsEntity = new Entity();
@@ -278,7 +271,6 @@ private static List<MapScriptAction> CreateMapScriptActions(ScriptAction[] actio
HeightMap heightMap,
BlendTileData blendTileData,
TerrainMaterial terrainMaterial,
EffectPipelineStateHandle pipelineStateHandle,
TerrainPatchIndexBufferCache indexBufferCache)
{
const int numTilesPerPatch = TerrainComponent.PatchSize - 1;
@@ -310,7 +302,6 @@ private static List<MapScriptAction> CreateMapScriptActions(ScriptAction[] actio

terrainEntity.Components.Add(CreatePatch(
terrainMaterial,
pipelineStateHandle,
heightMap,
blendTileData,
patchBounds,
@@ -322,7 +313,6 @@ private static List<MapScriptAction> CreateMapScriptActions(ScriptAction[] actio

private TerrainPatchComponent CreatePatch(
TerrainMaterial terrainMaterial,
EffectPipelineStateHandle pipelineStateHandle,
HeightMap heightMap,
BlendTileData blendTileData,
Rectangle patchBounds,
@@ -344,7 +334,6 @@ private static List<MapScriptAction> CreateMapScriptActions(ScriptAction[] actio

return new TerrainPatchComponent(
terrainMaterial,
pipelineStateHandle,
patchBounds,
vertexBuffer,
indexBuffer,
@@ -329,13 +329,12 @@ private static ushort[] CreateIndices(W3dMesh w3dMesh)
var depthState = DepthStencilStateDescription.Default;
var blendState = BlendStateDescription.Opaque;

var pipelineStateHandle = new EffectPipelineState(
var material = new ShaderMaterial(effect);

material.PipelineState = new EffectPipelineState(
rasterizerState,
depthState,
blendState)
.GetHandle();

var material = new ShaderMaterial(effect);
blendState);

var materialConstantsResourceBinding = effect.GetParameter("MaterialConstants").ResourceBinding;
var materialConstantsBuffer = AddDisposable(OpenSage.LowLevel.Graphics3D.Buffer.CreateDynamic(
@@ -409,8 +408,7 @@ void setMaterialConstant<T>(string name, T value)
meshParts.Add(new ModelMeshPart(
0,
w3dMesh.Header.NumTris * 3,
material,
pipelineStateHandle));
material));

return new ModelMeshMaterialPass(
contentManager.GraphicsDevice,
@@ -656,13 +654,12 @@ IEnumerable<uint> getExpandedVertexMaterialIDs()
blendState.DestinationBlend = w3dShader.DestBlend.ToBlend(false);
blendState.DestinationAlphaBlend = w3dShader.DestBlend.ToBlend(true);

var pipelineStateHandle = new EffectPipelineState(
var effectMaterial = new FixedFunctionMaterial(contentManager.EffectLibrary.FixedFunction);

effectMaterial.PipelineState = new EffectPipelineState(
rasterizerState,
depthState,
blendState)
.GetHandle();

var effectMaterial = new FixedFunctionMaterial(contentManager.EffectLibrary.FixedFunction);
blendState);

var materialConstantsBuffer = AddDisposable(Buffer<FixedFunctionMaterial.MaterialConstants>.CreateStatic(
contentManager.GraphicsDevice,
@@ -681,8 +678,7 @@ IEnumerable<uint> getExpandedVertexMaterialIDs()
return new ModelMeshPart(
startIndex,
indexCount,
effectMaterial,
pipelineStateHandle);
effectMaterial);
}

private static Animation CreateAnimation(W3dAnimation w3dAnimation)
@@ -134,7 +134,7 @@ public Entity GetParent()

public IEnumerable<Entity> GetChildren()
{
return Transform.Children.Select(x => x.Entity);
return Transform.Children.Select(x => x.Entity).ToList();
}

public Entity FindRoot()
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using OpenSage.Graphics.Rendering;

namespace OpenSage
{
@@ -87,5 +88,7 @@ public virtual void Update(GameTime gameTime)
public virtual void Draw(GameTime gameTime)
{
}

internal virtual void BuildRenderList(RenderList renderList) { }
}
}
@@ -9,6 +9,8 @@ namespace OpenSage.Graphics.Effects
{
public sealed class Effect : GraphicsObject
{
private static byte _nextID = 0;

private readonly GraphicsDevice _graphicsDevice;

private VertexDescriptor _vertexDescriptor;
@@ -19,12 +21,15 @@ public sealed class Effect : GraphicsObject

private readonly Dictionary<string, EffectParameter> _parameters;

private EffectPipelineStateHandle _pipelineStateHandle;
private PipelineState _pipelineState;

private EffectDirtyFlags _dirtyFlags;

public GraphicsDevice GraphicsDevice => _graphicsDevice;

public byte ID { get; }

[Flags]
private enum EffectDirtyFlags
{
@@ -40,6 +45,8 @@ private enum EffectDirtyFlags
{
_graphicsDevice = graphicsDevice;

ID = _nextID++;

using (var shaderStream = typeof(Effect).Assembly.GetManifestResourceStream($"OpenSage.Graphics.Shaders.{shaderName}.fxo"))
using (var shaderReader = new BinaryReader(shaderStream))
{
@@ -98,6 +105,12 @@ public void Apply(CommandEncoder commandEncoder)

public void SetPipelineState(EffectPipelineStateHandle pipelineStateHandle)
{
if (_pipelineStateHandle == pipelineStateHandle)
{
return;
}

_pipelineStateHandle = pipelineStateHandle;
_pipelineState = GetPipelineState(pipelineStateHandle);
_dirtyFlags |= EffectDirtyFlags.PipelineState;
}
@@ -1,17 +1,25 @@
using System.Collections.Generic;
using OpenSage.LowLevel.Graphics3D;
using OpenSage.LowLevel.Graphics3D.Util;

namespace OpenSage.Graphics.Effects
{
public class EffectMaterial
{
private static ushort _nextID = 0;

private readonly Dictionary<string, EffectMaterialProperty> _properties;

public Effect Effect { get; }

public EffectPipelineState PipelineState { get; set; }

public ushort ID { get; }

public EffectMaterial(Effect effect)
{
// TODO: This can overflow.
ID = _nextID++;

Effect = effect;

_properties = new Dictionary<string, EffectMaterialProperty>();
@@ -51,6 +59,8 @@ public void SetProperty(string name, SamplerState sampler)

public void Apply()
{
Effect.SetPipelineState(PipelineState.GetHandle());

foreach (var property in _properties.Values)
{
property.Parameter.SetData(property.Data);
@@ -1,5 +1,7 @@
using System.Numerics;
using System.Runtime.InteropServices;
using OpenSage.LowLevel.Graphics3D;
using OpenSage.Mathematics;

namespace OpenSage.Graphics.Effects
{
@@ -11,6 +13,16 @@ protected MeshMaterial(Effect effect)
SetProperty("Sampler", effect.GraphicsDevice.SamplerAnisotropicWrap);
}

public void SetSkinningBuffer(Buffer<Matrix4x3> skinningBuffer)
{
SetProperty("SkinningBuffer", skinningBuffer);
}

public void SetMeshConstants(Buffer<MeshConstants> meshConstants)
{
SetProperty("MeshConstants", meshConstants);
}

[StructLayout(LayoutKind.Sequential)]
public struct MeshConstants
{
@@ -8,7 +8,16 @@ public sealed class SpriteMaterial : EffectMaterial
public SpriteMaterial(Effect effect)
: base(effect)
{
SetProperty("Sampler", effect.GraphicsDevice.SamplerLinearClamp);
SetProperty("Sampler", effect.GraphicsDevice.SamplerPointClamp);

// TODO: Clean this up.
var rasterizerState = RasterizerStateDescription.CullBackSolid;
rasterizerState.IsFrontCounterClockwise = false;

PipelineState = new EffectPipelineState(
rasterizerState,
DepthStencilStateDescription.None,
BlendStateDescription.AlphaBlend);
}

public void SetMaterialConstants(Buffer<MaterialConstants> buffer)
@@ -1,27 +1,27 @@
using System.Collections.Generic;
using OpenSage.Graphics.Cameras;
using OpenSage.Graphics.Rendering;
using OpenSage.Terrain;

namespace OpenSage.Graphics
{
public sealed class GraphicsSystem : GameSystem
{
private readonly RenderContext _renderContext;
private readonly List<ModelComponent> _models;

private readonly List<MeshComponent> _meshes;
private readonly List<TerrainPatchComponent> _terrainPatches;

private readonly CameraInputMessageHandler _cameraInputMessageHandler;
private CameraInputState _cameraInputState;

private RenderPipeline _renderPipeline;

internal readonly RenderList RenderList = new RenderList();

public GraphicsSystem(Game game)
: base(game)
{
RegisterComponentList(_models = new List<ModelComponent>());

RenderList = AddDisposable(new RenderList());
RegisterComponentList(_meshes = new List<MeshComponent>());
RegisterComponentList(_terrainPatches = new List<TerrainPatchComponent>());

_renderContext = new RenderContext();

@@ -37,23 +37,15 @@ public override void Initialize()
base.Initialize();
}

internal override void OnEntityComponentAdded(EntityComponent component)
internal override void BuildRenderList(RenderList renderList)
{
base.OnEntityComponentAdded(component);

if (component is RenderableComponent r)
foreach (var renderable in _meshes)
{
r.BuildRenderList(RenderList);
renderable.BuildRenderList(renderList);
}
}

internal override void OnEntityComponentRemoved(EntityComponent component)
{
base.OnEntityComponentRemoved(component);

if (component is RenderableComponent r)
foreach (var renderable in _terrainPatches)
{
RenderList.RemoveRenderable(r);
renderable.BuildRenderList(renderList);
}
}

Oops, something went wrong.

0 comments on commit 61994be

Please sign in to comment.