Skip to content

Commit

Permalink
Apply gamma correction using OpenGL and not shaders for now.
Browse files Browse the repository at this point in the history
  • Loading branch information
softwareantics committed Jan 9, 2024
1 parent 102ea00 commit e2848da
Show file tree
Hide file tree
Showing 19 changed files with 100 additions and 48 deletions.
11 changes: 4 additions & 7 deletions FinalEngine.Examples.Sponza/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
using FinalEngine.Rendering.OpenGL.Invocation;
using FinalEngine.Rendering.Primitives;
using FinalEngine.Rendering.Renderers;
using FinalEngine.Rendering.Textures;
using FinalEngine.Resources;
using FinalEngine.Runtime;
using FinalEngine.Runtime.Invocation;
Expand Down Expand Up @@ -76,7 +75,7 @@ private static void Main()
renderPipeline.Initialize();

ResourceManager.Instance.RegisterLoader(new ShaderResourceLoader(fileSystem, renderDevice));
ResourceManager.Instance.RegisterLoader(new Texture2DResourceLoader(fileSystem, renderDevice.Factory));
ResourceManager.Instance.RegisterLoader(new Texture2DResourceLoader(fileSystem, renderDevice));
ResourceManager.Instance.RegisterLoader(new ShaderProgramResourceLoader(ResourceManager.Instance, renderDevice, fileSystem));

renderDevice.Pipeline.AddShaderHeader("lighting", fileSystem.File.ReadAllText("Resources\\Shaders\\Includes\\lighting.glsl"));
Expand Down Expand Up @@ -128,9 +127,7 @@ private static void Main()

var material = new Material()
{
DiffuseTexture = ResourceManager.Instance.LoadResource<ITexture2D>("Resources\\Textures\\Bricks\\bricks_diffuse.tga"),
NormalTexture = ResourceManager.Instance.LoadResource<ITexture2D>("Resources\\Textures\\Bricks\\bricks_normal.tga"),
SpecularTexture = ResourceManager.Instance.LoadResource<ITexture2D>("Resources\\Textures\\Bricks\\bricks_specular.tga"),
Shininess = 16.0f,
};

bool isRunning = true;
Expand All @@ -146,8 +143,8 @@ private static void Main()
var light = new Light()
{
Type = LightType.Directional,
Intensity = 0.4f,
Color = new Vector3(0.6f, 0.4f, 0.2f),
Intensity = 0.5f,
Color = new Vector3(1f),
Transform = new Transform()
{
Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(45.0f)),
Expand Down
42 changes: 21 additions & 21 deletions FinalEngine.Rendering.OpenGL/Buffers/OpenGLFrameBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,57 @@ namespace FinalEngine.Rendering.OpenGL.Buffers;

using System;
using System.Collections.Generic;
using System.Linq;
using FinalEngine.Rendering.Buffers;
using FinalEngine.Rendering.Exceptions;
using FinalEngine.Rendering.OpenGL.Invocation;
using FinalEngine.Rendering.OpenGL.Textures;
using FinalEngine.Rendering.Textures;
using OpenTK.Graphics.OpenGL4;

public class OpenGLFrameBuffer : IFrameBuffer, IOpenGLFrameBuffer, IDisposable
public class OpenGLFrameBuffer : IFrameBuffer, IOpenGLFrameBuffer
{
private readonly IOpenGLInvoker invoker;

private int rendererID;

public OpenGLFrameBuffer(IOpenGLInvoker invoker, IReadOnlyList<IOpenGLTexture> colorTargets, IOpenGLTexture? depthTarget)
public OpenGLFrameBuffer(IOpenGLInvoker invoker, IReadOnlyList<IOpenGLTexture>? colorTargets, IOpenGLTexture? depthTarget)
{
ArgumentNullException.ThrowIfNull(colorTargets, nameof(colorTargets));
this.invoker = invoker ?? throw new ArgumentNullException(nameof(invoker));

int maximumColorAttachments = this.invoker.GetInteger(GetPName.MaxColorAttachments);
int colorAttachmentCount = colorTargets?.Count ?? 0;

if (colorTargets.Count > maximumColorAttachments)
if (colorAttachmentCount > maximumColorAttachments)
{
throw new FrameBufferTargetException($"The number of {nameof(colorTargets)} should not exceed the maximum number of color attachmemts: '{maximumColorAttachments}'.");
}

this.DepthTarget = (ITexture2D?)depthTarget;
this.ColorTargets = colorTargets.Cast<ITexture2D>();
this.rendererID = invoker.CreateFramebuffer();

int attachmentCount = colorTargets.Count;

for (int i = 0; i < attachmentCount; i++)
for (int i = 0; i < colorAttachmentCount; i++)
{
colorTargets[i].Attach(FramebufferAttachment.ColorAttachment0 + i, this.rendererID);
colorTargets![i].Attach(FramebufferAttachment.ColorAttachment0 + i, this.rendererID);
}

Span<DrawBuffersEnum> bufs = stackalloc DrawBuffersEnum[attachmentCount];

for (int i = 0; i < attachmentCount; i++)
if (colorAttachmentCount > 0)
{
bufs[i] = DrawBuffersEnum.ColorAttachment0 + i;
Span<DrawBuffersEnum> bufs = stackalloc DrawBuffersEnum[colorAttachmentCount];

for (int i = 0; i < colorAttachmentCount; i++)
{
bufs[i] = DrawBuffersEnum.ColorAttachment0 + i;
}

this.invoker.NamedFramebufferDrawBuffers(this.rendererID, colorAttachmentCount, ref bufs[0]);
}

this.invoker.NamedFramebufferDrawBuffers(this.rendererID, attachmentCount, ref bufs[0]);
depthTarget?.Attach(FramebufferAttachment.DepthStencilAttachment, this.rendererID);

if (colorAttachmentCount <= 0)
{
this.invoker.NamedFramebufferDrawBuffer(this.rendererID, DrawBufferMode.None);
this.invoker.NamedFramebufferReadBuffer(this.rendererID, ReadBufferMode.None);
}

var status = invoker.CheckNamedFramebufferStatus(this.rendererID, FramebufferTarget.Framebuffer);

if (status != FramebufferStatus.FramebufferComplete)
Expand All @@ -66,10 +70,6 @@ public OpenGLFrameBuffer(IOpenGLInvoker invoker, IReadOnlyList<IOpenGLTexture> c
this.Dispose(false);
}

public IEnumerable<ITexture2D> ColorTargets { get; }

public ITexture2D? DepthTarget { get; }

protected bool IsDisposed { get; private set; }

public void Bind()
Expand Down
4 changes: 4 additions & 0 deletions FinalEngine.Rendering.OpenGL/Invocation/IOpenGLInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,12 @@ void NamedBufferData<T2>(int buffer, int size, T2[] data, BufferUsageHint usage)
void NamedBufferSubData<T3>(int buffer, IntPtr offset, int size, T3[] data)
where T3 : struct;

void NamedFramebufferDrawBuffer(int framebuffer, DrawBufferMode buf);

void NamedFramebufferDrawBuffers(int fb, int n, ref DrawBuffersEnum bufs);

void NamedFramebufferReadBuffer(int framebuffer, ReadBufferMode buf);

void NamedFramebufferTexture(int framebuffer, FramebufferAttachment attachment, int texture, int level);

void PolygonMode(MaterialFace face, PolygonMode mode);
Expand Down
10 changes: 10 additions & 0 deletions FinalEngine.Rendering.OpenGL/Invocation/OpenGLInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,16 @@ public void NamedFramebufferDrawBuffers(int fb, int n, ref DrawBuffersEnum bufs)
GL.NamedFramebufferDrawBuffers(fb, n, ref bufs);
}

public void NamedFramebufferDrawBuffer(int framebuffer, DrawBufferMode buf)
{
GL.NamedFramebufferDrawBuffer(framebuffer, buf);
}

public void NamedFramebufferReadBuffer(int framebuffer, ReadBufferMode buf)
{
GL.NamedFramebufferReadBuffer(framebuffer, buf);
}

private static void DebugCallback(
DebugSource source,
DebugType type,
Expand Down
6 changes: 2 additions & 4 deletions FinalEngine.Rendering.OpenGL/OpenGLGPUResourceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ public OpenGLGPUResourceFactory(IOpenGLInvoker invoker, IEnumMapper mapper)
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}

public IFrameBuffer CreateFrameBuffer(IReadOnlyCollection<ITexture2D> colorTargets, ITexture2D? depthTarget = null)
public IFrameBuffer CreateFrameBuffer(IReadOnlyCollection<ITexture2D>? colorTargets, ITexture2D? depthTarget = null)
{
ArgumentNullException.ThrowIfNull(colorTargets, nameof(colorTargets));

if (depthTarget is not null and not IOpenGLTexture)
{
throw new ArgumentException($"The specified {nameof(depthTarget)} parameter is not of type {nameof(IOpenGLTexture)}.", nameof(depthTarget));
}

return new OpenGLFrameBuffer(this.invoker, colorTargets.Cast<IOpenGLTexture>().ToList().AsReadOnly(), (IOpenGLTexture?)depthTarget);
return new OpenGLFrameBuffer(this.invoker, colorTargets?.Cast<IOpenGLTexture>().ToList().AsReadOnly(), (IOpenGLTexture?)depthTarget);
}

public IIndexBuffer CreateIndexBuffer<T>(BufferUsageType type, IReadOnlyCollection<T> data, int sizeInBytes)
Expand Down
15 changes: 15 additions & 0 deletions FinalEngine.Rendering.OpenGL/OpenGLRasterizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@ public class OpenGLRasterizer : IRasterizer

private readonly IEnumMapper mapper;

private RasterStateDescription currentDescription;

public OpenGLRasterizer(IOpenGLInvoker invoker, IEnumMapper mapper)
{
this.invoker = invoker ?? throw new ArgumentNullException(nameof(invoker));
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}

public RasterStateDescription GetRasterState()
{
return this.currentDescription;
}

public Rectangle GetViewport()
{
int[] data = new int[4];
Expand All @@ -38,12 +45,20 @@ public Rectangle GetViewport()

public void SetRasterState(RasterStateDescription description)
{
if (this.currentDescription == description)
{
return;
}

this.invoker.Cap(EnableCap.CullFace, description.CullEnabled);
this.invoker.Cap(EnableCap.ScissorTest, description.ScissorEnabled);
this.invoker.Cap(EnableCap.Multisample, description.MultiSamplingEnabled);
this.invoker.Cap(EnableCap.FramebufferSrgb, description.GammaCorrectionEnabled);
this.invoker.CullFace(this.mapper.Forward<CullFaceMode>(description.CullMode));
this.invoker.FrontFace(this.mapper.Forward<FrontFaceDirection>(description.WindingDirection));
this.invoker.PolygonMode(MaterialFace.FrontAndBack, this.mapper.Forward<PolygonMode>(description.FillMode));

this.currentDescription = description;
}

public void SetScissor(Rectangle rectangle)
Expand Down
12 changes: 12 additions & 0 deletions FinalEngine.Rendering.OpenGL/OpenGLRenderDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public OpenGLRenderDevice(IOpenGLInvoker invoker)
{ SizedFormat.Rg8, SizedInternalFormat.Rg8 },
{ SizedFormat.Rgb8, All.Rgb8 },
{ SizedFormat.Rgba8, SizedInternalFormat.Rgba8 },
{ SizedFormat.Srgba, SizedInternalFormat.Srgb8Alpha8 },
{ BufferUsageType.Static, BufferUsageHint.StaticDraw },
{ BufferUsageType.Dynamic, BufferUsageHint.DynamicDraw },
};
Expand Down Expand Up @@ -139,4 +140,15 @@ public void DrawIndices(PrimitiveTopology topology, int first, int count)
{
this.invoker.DrawElements(this.mapper.Forward<PrimitiveType>(topology), count, DrawElementsType.UnsignedInt, first);
}

public void Initialize()
{
this.Rasterizer.SetRasterState(default);

this.OutputMerger.SetStencilState(default);
this.OutputMerger.SetDepthState(default);
this.OutputMerger.SetBlendState(default);

this.Pipeline.SetFrameBuffer(null);
}
}
8 changes: 2 additions & 6 deletions FinalEngine.Rendering/Buffers/IFrameBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

namespace FinalEngine.Rendering.Buffers;

using System.Collections.Generic;
using FinalEngine.Rendering.Textures;
using System;

public interface IFrameBuffer
public interface IFrameBuffer : IDisposable
{
IEnumerable<ITexture2D> ColorTargets { get; }

ITexture2D? DepthTarget { get; }
}
6 changes: 3 additions & 3 deletions FinalEngine.Rendering/FinalEngine.Rendering.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@
<None Update="Resources\Shaders\Lighting\lighting.point.frag">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Shaders\sprite-geometry.fesp">
<None Update="Resources\Shaders\Batching\sprite-geometry.fesp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Shaders\sprite-geometry.frag">
<None Update="Resources\Shaders\Batching\sprite-geometry.frag">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Shaders\sprite-geometry.vert">
<None Update="Resources\Shaders\Batching\sprite-geometry.vert">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\Shaders\standard-geometry.fesp">
Expand Down
2 changes: 1 addition & 1 deletion FinalEngine.Rendering/IGPUResourceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace FinalEngine.Rendering;

public interface IGPUResourceFactory
{
IFrameBuffer CreateFrameBuffer(IReadOnlyCollection<ITexture2D> colorTargets, ITexture2D? depthTarget = null);
IFrameBuffer CreateFrameBuffer(IReadOnlyCollection<ITexture2D>? colorTargets, ITexture2D? depthTarget = null);

IIndexBuffer CreateIndexBuffer<T>(BufferUsageType type, IReadOnlyCollection<T> data, int sizeInBytes)
where T : struct;
Expand Down
2 changes: 2 additions & 0 deletions FinalEngine.Rendering/IRasterizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace FinalEngine.Rendering;

public interface IRasterizer
{
RasterStateDescription GetRasterState();

Rectangle GetViewport();

void SetRasterState(RasterStateDescription description);
Expand Down
2 changes: 2 additions & 0 deletions FinalEngine.Rendering/IRenderDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ public interface IRenderDevice
void Clear(Color color, float depth = 1.0f, int stencil = 0);

void DrawIndices(PrimitiveTopology topology, int first, int count);

void Initialize();
}
16 changes: 10 additions & 6 deletions FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ namespace FinalEngine.Rendering.Loaders.Textures;

public class Texture2DResourceLoader : ResourceLoaderBase<ITexture2D>
{
private readonly IGPUResourceFactory factory;

private readonly IFileSystem fileSystem;

private readonly IImageInvoker invoker;

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_editor_common

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_editor_view_models

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_rendering

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_runtime

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_rendering_opengl

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

Check warning on line 22 in FinalEngine.Rendering/Loaders/Textures/Texture2DResourceLoader.cs

View workflow job for this annotation

GitHub Actions / build_editor_desktop

Change type of field 'invoker' from 'FinalEngine.Rendering.Loaders.Invocation.IImageInvoker' to 'FinalEngine.Rendering.Loaders.Invocation.ImageInvoker' for improved performance (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1859)

public Texture2DResourceLoader(IFileSystem fileSystem, IGPUResourceFactory factory)
private readonly IRenderDevice renderDevice;

public Texture2DResourceLoader(IFileSystem fileSystem, IRenderDevice renderDevice)
{
this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
this.renderDevice = renderDevice ?? throw new ArgumentNullException(nameof(renderDevice));
this.invoker = new ImageInvoker();
}

Expand Down Expand Up @@ -63,7 +63,9 @@ public override ITexture2D LoadResource(string filePath)
}
}

return this.factory.CreateTexture2D(
var rasterState = this.renderDevice.Rasterizer.GetRasterState();

return this.renderDevice.Factory.CreateTexture2D(
new Texture2DDescription()
{
Width = width,
Expand All @@ -79,7 +81,9 @@ public override ITexture2D LoadResource(string filePath)

GenerateMipmaps = true,
},
pixels.ToArray());
pixels.ToArray(),
PixelFormat.Rgba,
rasterState.GammaCorrectionEnabled ? SizedFormat.Srgba : SizedFormat.Rgb8);
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions FinalEngine.Rendering/RasterStateDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public struct RasterStateDescription : IEquatable<RasterStateDescription>

private RasterMode? fillMode;

private bool? gammaCorrectionEnabled;

private WindingDirection? windingDirection;

public bool CullEnabled { get; set; }
Expand All @@ -49,6 +51,12 @@ public RasterMode FillMode
set { this.fillMode = value; }
}

public bool GammaCorrectionEnabled
{
readonly get { return this.gammaCorrectionEnabled ?? true; }
set { this.gammaCorrectionEnabled = value; }
}

public bool MultiSamplingEnabled { get; set; }

public bool ScissorEnabled { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions FinalEngine.Rendering/RenderingEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public RenderingEngine(IRenderDevice renderDevice, IGeometryRenderer geometryRen
Type = LightType.Ambient,
Intensity = 0.1f,
};

this.renderDevice.Initialize();
}

private IShaderProgram GeometryProgram
Expand Down
2 changes: 2 additions & 0 deletions FinalEngine.Rendering/Textures/SizedFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public enum SizedFormat
Rgb8,

Rgba8,

Srgba,
}

0 comments on commit e2848da

Please sign in to comment.