mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
picking texture, not pixel perfect but good enough
This commit is contained in:
parent
a267c6233f
commit
cc89becb4c
|
|
@ -1 +1 @@
|
|||
Subproject commit 0c633f3d3ad6f1eed9df9cee60917e1e169a0101
|
||||
Subproject commit 00bc31fa4cc570efd3f9d54694feb16a8d21251c
|
||||
|
|
@ -103,6 +103,8 @@
|
|||
<None Remove="Resources\framebuffer.vert" />
|
||||
<None Remove="Resources\outline.frag" />
|
||||
<None Remove="Resources\outline.vert" />
|
||||
<None Remove="Resources\picking.frag" />
|
||||
<None Remove="Resources\picking.vert" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -122,6 +124,8 @@
|
|||
<EmbeddedResource Include="Resources\framebuffer.vert" />
|
||||
<EmbeddedResource Include="Resources\outline.frag" />
|
||||
<EmbeddedResource Include="Resources\outline.vert" />
|
||||
<EmbeddedResource Include="Resources\picking.frag" />
|
||||
<EmbeddedResource Include="Resources\picking.vert" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
13
FModel/Resources/picking.frag
Normal file
13
FModel/Resources/picking.frag
Normal file
|
|
@ -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);
|
||||
}
|
||||
15
FModel/Resources/picking.vert
Normal file
15
FModel/Resources/picking.vert
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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<uint> _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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
122
FModel/Views/Snooper/PickingTexture.cs
Normal file
122
FModel/Views/Snooper/PickingTexture.cs
Normal file
|
|
@ -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<FGuid,Model> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user