diff --git a/EpicManifestParser b/EpicManifestParser
index 0c633f3d..00bc31fa 160000
--- a/EpicManifestParser
+++ b/EpicManifestParser
@@ -1 +1 @@
-Subproject commit 0c633f3d3ad6f1eed9df9cee60917e1e169a0101
+Subproject commit 00bc31fa4cc570efd3f9d54694feb16a8d21251c
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index a6351c28..ee406e32 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -103,6 +103,8 @@
+
+
@@ -122,6 +124,8 @@
+
+
diff --git a/FModel/Framework/ImGuiController.cs b/FModel/Framework/ImGuiController.cs
index 808ad9ba..4c842309 100644
--- a/FModel/Framework/ImGuiController.cs
+++ b/FModel/Framework/ImGuiController.cs
@@ -32,7 +32,7 @@ public class ImGuiController : IDisposable
private int _windowWidth;
private int _windowHeight;
- private System.Numerics.Vector2 _scaleFactor = System.Numerics.Vector2.One;
+ private readonly System.Numerics.Vector2 _scaleFactor = System.Numerics.Vector2.One;
private static bool KHRDebugAvailable = false;
diff --git a/FModel/Resources/picking.frag b/FModel/Resources/picking.frag
new file mode 100644
index 00000000..11208c3c
--- /dev/null
+++ b/FModel/Resources/picking.frag
@@ -0,0 +1,13 @@
+#version 330
+
+uniform uint uA;
+uniform uint uB;
+uniform uint uC;
+uniform uint uD;
+
+out uvec4 FragColor;
+
+void main()
+{
+ FragColor = uvec4(uA, uB, uC, uD);
+}
diff --git a/FModel/Resources/picking.vert b/FModel/Resources/picking.vert
new file mode 100644
index 00000000..53ee7fff
--- /dev/null
+++ b/FModel/Resources/picking.vert
@@ -0,0 +1,15 @@
+#version 330 core
+
+layout (location = 1) in vec3 vPos;
+layout (location = 8) in mat4 vInstanceMatrix;
+layout (location = 12) in vec3 vMorphTarget;
+
+uniform mat4 uView;
+uniform mat4 uProjection;
+uniform float uMorphTime;
+
+void main()
+{
+ vec3 pos = mix(vPos, vMorphTarget, uMorphTime);
+ gl_Position = uProjection * uView * vInstanceMatrix * vec4(pos, 1.0);
+}
diff --git a/FModel/Views/Snooper/FramebufferObject.cs b/FModel/Views/Snooper/FramebufferObject.cs
index 0fba96d4..5d06f5b2 100644
--- a/FModel/Views/Snooper/FramebufferObject.cs
+++ b/FModel/Views/Snooper/FramebufferObject.cs
@@ -9,8 +9,8 @@ public class FramebufferObject : IDisposable
private int _framebufferHandle;
private int _postProcessingHandle;
- private readonly int _width;
- private readonly int _height;
+ private int _width;
+ private int _height;
private readonly RenderbufferObject _renderbuffer;
private BufferObject _ebo;
@@ -43,7 +43,7 @@ public class FramebufferObject : IDisposable
public void Setup()
{
_framebufferHandle = GL.GenFramebuffer();
- Bind(_framebufferHandle);
+ Bind();
_framebufferTexture = new Texture((uint) _width, (uint) _height);
@@ -102,6 +102,17 @@ public class FramebufferObject : IDisposable
public IntPtr GetPointer() => _postProcessingTexture.GetPointer();
+ public void WindowResized(int width, int height)
+ {
+ _width = width;
+ _height = height;
+
+ _renderbuffer.WindowResized(width, height);
+
+ _framebufferTexture.WindowResized(width, height);
+ _postProcessingTexture.WindowResized(width, height);
+ }
+
public void Dispose()
{
_vao.Dispose();
diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs
index 747d1d85..4a56fd61 100644
--- a/FModel/Views/Snooper/Model.cs
+++ b/FModel/Views/Snooper/Model.cs
@@ -266,6 +266,17 @@ public class Model : IDisposable
}
}
+ public void SimpleRender(Shader shader)
+ {
+ _vao.Bind();
+ shader.SetUniform("uMorphTime", MorphTime);
+ for (int section = 0; section < Sections.Length; section++)
+ {
+ Sections[section].Render(TransformsCount);
+ }
+ _vao.Unbind();
+ }
+
public void Outline(Shader shader)
{
GL.StencilMask(0x00);
diff --git a/FModel/Views/Snooper/PickingTexture.cs b/FModel/Views/Snooper/PickingTexture.cs
new file mode 100644
index 00000000..5c2b1d3d
--- /dev/null
+++ b/FModel/Views/Snooper/PickingTexture.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using CUE4Parse.UE4.Objects.Core.Misc;
+using OpenTK.Graphics.OpenGL4;
+using OpenTK.Mathematics;
+using Vector2 = System.Numerics.Vector2;
+
+namespace FModel.Views.Snooper;
+
+public class PickingTexture : IDisposable
+{
+ private int _width;
+ private int _height;
+
+ private int _framebufferHandle;
+
+ private Shader _shader;
+ private int _pickingTexture;
+ private int _depthTexture;
+
+ public PickingTexture(int width, int height)
+ {
+ _width = width;
+ _height = height;
+ }
+
+ public void Setup()
+ {
+ _framebufferHandle = GL.GenFramebuffer();
+ Bind();
+
+ _shader = new Shader("picking");
+
+ _pickingTexture = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, _pickingTexture);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32ui, _width, _height, 0, PixelFormat.RgbaInteger, PixelType.UnsignedInt, IntPtr.Zero);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Nearest);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _pickingTexture, 0);
+
+ _depthTexture = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, _depthTexture);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent, _width, _height, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, _depthTexture, 0);
+
+ var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
+ if (status != FramebufferErrorCode.FramebufferComplete)
+ {
+ throw new Exception($"Framebuffer failed to bind with error: {GL.GetProgramInfoLog(_framebufferHandle)}");
+ }
+
+ GL.BindTexture(TextureTarget.Texture2D, 0);
+ Bind(0);
+ }
+
+ public void Render(Matrix4 viewMatrix, Matrix4 projMatrix, IDictionary models)
+ {
+ Bind();
+ GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+
+ _shader.Use();
+ _shader.SetUniform("uView", viewMatrix);
+ _shader.SetUniform("uProjection", projMatrix);
+
+ foreach ((FGuid guid, Model model) in models)
+ {
+ _shader.SetUniform("uA", guid.A);
+ _shader.SetUniform("uB", guid.B);
+ _shader.SetUniform("uC", guid.C);
+ _shader.SetUniform("uD", guid.D);
+
+ if (!model.Show) continue;
+ model.SimpleRender(_shader);
+ }
+
+ Bind(0);
+ }
+
+ public void Bind() => Bind(_framebufferHandle);
+ public void Bind(int handle)
+ {
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, handle);
+ }
+
+ public FGuid ReadPixel(Vector2 mousePos, Vector2 windowPos, Vector2 windowSize)
+ {
+ Bind();
+ FGuid pixel = default;
+
+ var scaleX = windowSize.X / _width;
+ var scaleY = windowSize.Y / _height;
+ var x = Convert.ToInt32((mousePos.X - windowPos.X) / scaleX);
+ var y = -Convert.ToInt32((mousePos.Y - windowPos.Y) / scaleY);
+
+ GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
+ GL.ReadPixels(x, y, 1, 1, PixelFormat.RgbaInteger, PixelType.UnsignedInt, ref pixel);
+ GL.ReadBuffer(ReadBufferMode.None);
+
+ Bind(0);
+ return pixel;
+ }
+
+ public void WindowResized(int width, int height)
+ {
+ _width = width;
+ _height = height;
+
+ GL.BindTexture(TextureTarget.Texture2D, _pickingTexture);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32ui, _width, _height, 0, PixelFormat.RgbaInteger, PixelType.UnsignedInt, IntPtr.Zero);
+
+ GL.BindTexture(TextureTarget.Texture2D, _depthTexture);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent, _width, _height, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
+ }
+
+ public void Dispose()
+ {
+ _shader?.Dispose();
+ GL.DeleteTexture(_pickingTexture);
+ GL.DeleteTexture(_depthTexture);
+ GL.DeleteFramebuffer(_framebufferHandle);
+ }
+}
diff --git a/FModel/Views/Snooper/RenderbufferObject.cs b/FModel/Views/Snooper/RenderbufferObject.cs
index 30fac53b..6ff1ceb4 100644
--- a/FModel/Views/Snooper/RenderbufferObject.cs
+++ b/FModel/Views/Snooper/RenderbufferObject.cs
@@ -7,8 +7,8 @@ public class RenderbufferObject : IDisposable
{
private int _handle;
- private readonly int _width;
- private readonly int _height;
+ private int _width;
+ private int _height;
public RenderbufferObject(int width, int height)
{
@@ -25,6 +25,15 @@ public class RenderbufferObject : IDisposable
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, _handle);
}
+ public void WindowResized(int width, int height)
+ {
+ _width = width;
+ _height = height;
+
+ GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, _handle);
+ GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, Constants.SAMPLES_COUNT, RenderbufferStorage.Depth24Stencil8, _width, _height);
+ }
+
public void Dispose()
{
GL.DeleteRenderbuffer(_handle);
diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs
index 5919ecf8..65fa4fcc 100644
--- a/FModel/Views/Snooper/Renderer.cs
+++ b/FModel/Views/Snooper/Renderer.cs
@@ -22,11 +22,13 @@ public class Renderer : IDisposable
private Vector3 _diffuseLight;
private Vector3 _specularLight;
+ public PickingTexture Picking { get; }
public Cache Cache { get; }
public Options Settings { get; }
- public Renderer()
+ public Renderer(int width, int height)
{
+ Picking = new PickingTexture(width, height);
Cache = new Cache();
Settings = new Options();
}
@@ -60,6 +62,7 @@ public class Renderer : IDisposable
_diffuseLight = new Vector3(0.75f);
_specularLight = new Vector3(0.5f);
+ Picking.Setup();
Cache.Setup();
}
@@ -85,6 +88,8 @@ public class Renderer : IDisposable
Cache.Render(_shader);
GL.Enable(EnableCap.StencilTest);
Cache.Outline(_outline);
+
+ Picking.Render(viewMatrix, projMatrix, Cache.Models);
}
private Camera SetupCamera(FBox box)
@@ -222,6 +227,7 @@ public class Renderer : IDisposable
{
_shader.Dispose();
_outline.Dispose();
+ Picking.Dispose();
Cache.Dispose();
}
}
diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs
index 876ec978..1b6cab06 100644
--- a/FModel/Views/Snooper/SnimGui.cs
+++ b/FModel/Views/Snooper/SnimGui.cs
@@ -1,5 +1,4 @@
using System;
-using System.Windows;
using CUE4Parse.UE4.Objects.Core.Misc;
using FModel.Framework;
using ImGuiNET;
@@ -449,15 +448,20 @@ public class SnimGui
_viewportFocus = true;
s.CursorState = CursorState.Grabbed;
}
+ if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
+ {
+ var guid = s.Renderer.Picking.ReadPixel(ImGui.GetMousePos(), ImGui.GetCursorScreenPos(), size);
+ s.Renderer.Settings.SelectModel(guid);
+ }
}
// this can't be inside IsItemHovered! read it as
// if left mouse button was pressed while hovering the viewport
// move camera until left mouse button is released
// no matter where mouse position end up
- var io = ImGui.GetIO();
if (ImGui.IsMouseDragging(ImGuiMouseButton.Left, lookSensitivity) && _viewportFocus)
{
+ var io = ImGui.GetIO();
var delta = io.MouseDelta * lookSensitivity;
s.Camera.ModifyDirection(delta.X, delta.Y);
}
diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs
index ac8a616c..ec3a5dc2 100644
--- a/FModel/Views/Snooper/Snooper.cs
+++ b/FModel/Views/Snooper/Snooper.cs
@@ -13,7 +13,7 @@ namespace FModel.Views.Snooper;
public class Snooper : GameWindow
{
public Camera Camera;
- public FramebufferObject Framebuffer;
+ public readonly FramebufferObject Framebuffer;
public readonly Renderer Renderer;
private readonly Skybox _skybox;
@@ -26,8 +26,8 @@ public class Snooper : GameWindow
public Snooper(GameWindowSettings gwSettings, NativeWindowSettings nwSettings) : base(gwSettings, nwSettings)
{
- Framebuffer = new FramebufferObject(Size);
- Renderer = new Renderer();
+ Framebuffer = new FramebufferObject(ClientSize);
+ Renderer = new Renderer(ClientSize.X, ClientSize.Y);
_skybox = new Skybox();
_grid = new Grid();
@@ -87,9 +87,10 @@ public class Snooper : GameWindow
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
Framebuffer.Setup();
+ Renderer.Setup();
+
_skybox.Setup();
_grid.Setup();
- Renderer.Setup();
_init = true;
}
@@ -177,9 +178,10 @@ public class Snooper : GameWindow
GL.Viewport(0, 0, e.Width, e.Height);
- Framebuffer = new FramebufferObject(e.Size);
- Framebuffer.Setup();
Camera.AspectRatio = e.Width / (float) e.Height;
+ Framebuffer.WindowResized(e.Width, e.Height);
+ Renderer.Picking.WindowResized(e.Width, e.Height);
+
_gui.Controller.WindowResized(e.Width, e.Height);
}
@@ -187,9 +189,11 @@ public class Snooper : GameWindow
{
base.Dispose(disposing);
+ Framebuffer?.Dispose();
+ Renderer?.Dispose();
+
_skybox?.Dispose();
_grid?.Dispose();
- Renderer?.Dispose();
_gui?.Controller.Dispose();
}
}
diff --git a/FModel/Views/Snooper/Texture.cs b/FModel/Views/Snooper/Texture.cs
index 1df8f377..44545e27 100644
--- a/FModel/Views/Snooper/Texture.cs
+++ b/FModel/Views/Snooper/Texture.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Windows;
using CUE4Parse.UE4.Assets.Exports.Texture;
using OpenTK.Graphics.OpenGL4;
@@ -12,6 +12,7 @@ public class Texture : IDisposable
{
private readonly int _handle;
private readonly TextureType _type;
+ private readonly TextureTarget _target;
public readonly string Type;
public readonly string Name;
@@ -19,14 +20,20 @@ public class Texture : IDisposable
public readonly EPixelFormat Format;
public readonly uint ImportedWidth;
public readonly uint ImportedHeight;
- public readonly int Width;
- public readonly int Height;
+ public int Width;
+ public int Height;
public string Label;
public Texture(TextureType type)
{
_handle = GL.GenTexture();
_type = type;
+ _target = _type switch
+ {
+ TextureType.Cubemap => TextureTarget.TextureCubeMap,
+ TextureType.MsaaFramebuffer => TextureTarget.Texture2DMultisample,
+ _ => TextureTarget.Texture2D
+ };
Label = "(?) Click to Copy Path";
}
@@ -38,12 +45,12 @@ public class Texture : IDisposable
GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, Constants.SAMPLES_COUNT, PixelInternalFormat.Rgb, Width, Height, true);
- GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest);
- GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Nearest);
- GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
- GL.TexParameter(TextureTarget.Texture2DMultisample, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest);
+ GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Nearest);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
- GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _handle, 0);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _target, _handle, 0);
}
public Texture(int width, int height) : this(TextureType.Framebuffer)
@@ -52,14 +59,14 @@ public class Texture : IDisposable
Height = height;
Bind(TextureUnit.Texture0);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
+ GL.TexImage2D(_target, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
- GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _handle, 0);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _target, _handle, 0);
}
public Texture(byte[] data, int width, int height, UTexture2D texture2D) : this(TextureType.Normal)
@@ -74,11 +81,11 @@ public class Texture : IDisposable
Height = height;
Bind(TextureUnit.Texture0);
- GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
- GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 8);
+ GL.TexImage2D(_target, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data);
+ GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
+ GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureBaseLevel, 0);
+ GL.TexParameter(_target, TextureParameterName.TextureMaxLevel, 8);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
}
@@ -104,39 +111,34 @@ public class Texture : IDisposable
});
}
- GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
- GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int) TextureWrapMode.ClampToEdge);
- GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
- GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapR, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
+ GL.TexParameter(_target, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
}
public Texture(uint width, uint height, IntPtr data) : this(TextureType.Normal)
{
Width = (int) width;
Height = (int) height;
- Bind(TextureTarget.Texture2D);
+ Bind(_target);
GL.TexStorage2D(TextureTarget2d.Texture2D, 1, SizedInternalFormat.Rgba8, Width, Height);
- GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
+ GL.TexSubImage2D(_target, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, data);
var repeat = (int) TextureWrapMode.Repeat;
- GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, ref repeat);
- GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, ref repeat);
+ GL.TexParameterI(_target, TextureParameterName.TextureWrapS, ref repeat);
+ GL.TexParameterI(_target, TextureParameterName.TextureWrapT, ref repeat);
var zero = 1 - 1;
- GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, ref zero);
+ GL.TexParameterI(_target, TextureParameterName.TextureMaxLevel, ref zero);
}
public void Bind(TextureUnit textureSlot)
{
GL.ActiveTexture(textureSlot);
- Bind(_type switch
- {
- TextureType.Cubemap => TextureTarget.TextureCubeMap,
- TextureType.MsaaFramebuffer => TextureTarget.Texture2DMultisample,
- _ => TextureTarget.Texture2D
- });
+ Bind(_target);
}
public void Bind(TextureTarget target)
@@ -144,8 +146,34 @@ public class Texture : IDisposable
GL.BindTexture(target, _handle);
}
+ public void Bind()
+ {
+ GL.BindTexture(_target, _handle);
+ }
+
public IntPtr GetPointer() => (IntPtr) _handle;
+ public void WindowResized(int width, int height)
+ {
+ Width = width;
+ Height = height;
+
+ Bind();
+ switch (_type)
+ {
+ case TextureType.MsaaFramebuffer:
+ GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, Constants.SAMPLES_COUNT, PixelInternalFormat.Rgb, Width, Height, true);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _target, _handle, 0);
+ break;
+ case TextureType.Framebuffer:
+ GL.TexImage2D(_target, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
+ GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _target, _handle, 0);
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
public void Dispose()
{
GL.DeleteTexture(_handle);