mirror of
https://github.com/4sval/FModel.git
synced 2026-04-18 15:47:43 -05:00
cached textures
This commit is contained in:
parent
4da6b2d775
commit
b32d77601e
|
|
@ -1 +1 @@
|
|||
Subproject commit 6bb149f6fa34ef0cc51c60df9334678727d29853
|
||||
Subproject commit a048e1373b71c504b01de4cd89bebe4e01cb3d11
|
||||
|
|
@ -132,6 +132,7 @@
|
|||
<PackageReference Include="CSCore" Version="1.2.1.2" />
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
||||
<PackageReference Include="EpicManifestParser" Version="1.2.70-temp" />
|
||||
<PackageReference Include="ImGui.NET" Version="1.87.3" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.2.16" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.4" />
|
||||
|
|
|
|||
539
FModel/Framework/ImGuiController.cs
Normal file
539
FModel/Framework/ImGuiController.cs
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ImGuiNET;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Windowing.Desktop;
|
||||
using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
using ErrorCode = OpenTK.Graphics.OpenGL4.ErrorCode;
|
||||
|
||||
namespace FModel.Framework;
|
||||
|
||||
public class ImGuiController : IDisposable
|
||||
{
|
||||
private bool _frameBegun;
|
||||
|
||||
private int _vertexArray;
|
||||
private int _vertexBuffer;
|
||||
private int _vertexBufferSize;
|
||||
private int _indexBuffer;
|
||||
private int _indexBufferSize;
|
||||
|
||||
//private Texture _fontTexture;
|
||||
|
||||
private int _fontTexture;
|
||||
|
||||
private int _shader;
|
||||
private int _shaderFontTextureLocation;
|
||||
private int _shaderProjectionMatrixLocation;
|
||||
|
||||
private int _windowWidth;
|
||||
private int _windowHeight;
|
||||
|
||||
private System.Numerics.Vector2 _scaleFactor = System.Numerics.Vector2.One;
|
||||
|
||||
private static bool KHRDebugAvailable = false;
|
||||
|
||||
public ImGuiController(int width, int height)
|
||||
{
|
||||
_windowWidth = width;
|
||||
_windowHeight = height;
|
||||
|
||||
int major = GL.GetInteger(GetPName.MajorVersion);
|
||||
int minor = GL.GetInteger(GetPName.MinorVersion);
|
||||
|
||||
KHRDebugAvailable = (major == 4 && minor >= 3) || IsExtensionSupported("KHR_debug");
|
||||
|
||||
IntPtr context = ImGui.CreateContext();
|
||||
ImGui.SetCurrentContext(context);
|
||||
var io = ImGui.GetIO();
|
||||
io.Fonts.AddFontDefault();
|
||||
io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 16);
|
||||
|
||||
io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
|
||||
|
||||
CreateDeviceResources();
|
||||
SetKeyMappings();
|
||||
|
||||
SetPerFrameImGuiData(1f / 60f);
|
||||
|
||||
ImGui.NewFrame();
|
||||
_frameBegun = true;
|
||||
}
|
||||
|
||||
public void WindowResized(int width, int height)
|
||||
{
|
||||
_windowWidth = width;
|
||||
_windowHeight = height;
|
||||
}
|
||||
|
||||
public void DestroyDeviceObjects()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void CreateDeviceResources()
|
||||
{
|
||||
_vertexBufferSize = 10000;
|
||||
_indexBufferSize = 2000;
|
||||
|
||||
int prevVAO = GL.GetInteger(GetPName.VertexArrayBinding);
|
||||
int prevArrayBuffer = GL.GetInteger(GetPName.ArrayBufferBinding);
|
||||
|
||||
_vertexArray = GL.GenVertexArray();
|
||||
GL.BindVertexArray(_vertexArray);
|
||||
LabelObject(ObjectLabelIdentifier.VertexArray, _vertexArray, "ImGui");
|
||||
|
||||
_vertexBuffer = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer);
|
||||
LabelObject(ObjectLabelIdentifier.Buffer, _vertexBuffer, "VBO: ImGui");
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, _vertexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
|
||||
|
||||
_indexBuffer = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer);
|
||||
LabelObject(ObjectLabelIdentifier.Buffer, _indexBuffer, "EBO: ImGui");
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, _indexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
|
||||
|
||||
RecreateFontDeviceTexture();
|
||||
|
||||
string VertexSource = @"#version 330 core
|
||||
uniform mat4 projection_matrix;
|
||||
layout(location = 0) in vec2 in_position;
|
||||
layout(location = 1) in vec2 in_texCoord;
|
||||
layout(location = 2) in vec4 in_color;
|
||||
out vec4 color;
|
||||
out vec2 texCoord;
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection_matrix * vec4(in_position, 0, 1);
|
||||
color = in_color;
|
||||
texCoord = in_texCoord;
|
||||
}";
|
||||
string FragmentSource = @"#version 330 core
|
||||
uniform sampler2D in_fontTexture;
|
||||
in vec4 color;
|
||||
in vec2 texCoord;
|
||||
out vec4 outputColor;
|
||||
void main()
|
||||
{
|
||||
outputColor = color * texture(in_fontTexture, texCoord);
|
||||
}";
|
||||
|
||||
_shader = CreateProgram("ImGui", VertexSource, FragmentSource);
|
||||
_shaderProjectionMatrixLocation = GL.GetUniformLocation(_shader, "projection_matrix");
|
||||
_shaderFontTextureLocation = GL.GetUniformLocation(_shader, "in_fontTexture");
|
||||
|
||||
int stride = Unsafe.SizeOf<ImDrawVert>();
|
||||
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, stride, 0);
|
||||
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, stride, 8);
|
||||
GL.VertexAttribPointer(2, 4, VertexAttribPointerType.UnsignedByte, true, stride, 16);
|
||||
|
||||
GL.EnableVertexAttribArray(0);
|
||||
GL.EnableVertexAttribArray(1);
|
||||
GL.EnableVertexAttribArray(2);
|
||||
|
||||
GL.BindVertexArray(prevVAO);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, prevArrayBuffer);
|
||||
|
||||
CheckGLError("End of ImGui setup");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recreates the device texture used to render text.
|
||||
/// </summary>
|
||||
public void RecreateFontDeviceTexture()
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
io.Fonts.GetTexDataAsRGBA32(out IntPtr pixels, out int width, out int height, out int bytesPerPixel);
|
||||
|
||||
int mips = (int)Math.Floor(Math.Log(Math.Max(width, height), 2));
|
||||
|
||||
int prevActiveTexture = GL.GetInteger(GetPName.ActiveTexture);
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
int prevTexture2D = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
|
||||
_fontTexture = GL.GenTexture();
|
||||
GL.BindTexture(TextureTarget.Texture2D, _fontTexture);
|
||||
GL.TexStorage2D(TextureTarget2d.Texture2D, mips, SizedInternalFormat.Rgba8, width, height);
|
||||
LabelObject(ObjectLabelIdentifier.Texture, _fontTexture, "ImGui Text Atlas");
|
||||
|
||||
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, width, height, PixelFormat.Bgra, PixelType.UnsignedByte, pixels);
|
||||
|
||||
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, mips - 1);
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
||||
|
||||
// Restore state
|
||||
GL.BindTexture(TextureTarget.Texture2D, prevTexture2D);
|
||||
GL.ActiveTexture((TextureUnit)prevActiveTexture);
|
||||
|
||||
io.Fonts.SetTexID((IntPtr)_fontTexture);
|
||||
|
||||
io.Fonts.ClearTexData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the ImGui draw list data.
|
||||
/// </summary>
|
||||
public void Render()
|
||||
{
|
||||
if (_frameBegun)
|
||||
{
|
||||
_frameBegun = false;
|
||||
ImGui.Render();
|
||||
RenderImDrawData(ImGui.GetDrawData());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates ImGui input and IO configuration state.
|
||||
/// </summary>
|
||||
public void Update(GameWindow wnd, float deltaSeconds)
|
||||
{
|
||||
if (_frameBegun)
|
||||
{
|
||||
ImGui.Render();
|
||||
}
|
||||
|
||||
SetPerFrameImGuiData(deltaSeconds);
|
||||
UpdateImGuiInput(wnd);
|
||||
|
||||
_frameBegun = true;
|
||||
ImGui.NewFrame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets per-frame data based on the associated window.
|
||||
/// This is called by Update(float).
|
||||
/// </summary>
|
||||
private void SetPerFrameImGuiData(float deltaSeconds)
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
io.DisplaySize = new System.Numerics.Vector2(
|
||||
_windowWidth / _scaleFactor.X,
|
||||
_windowHeight / _scaleFactor.Y);
|
||||
io.DisplayFramebufferScale = _scaleFactor;
|
||||
io.DeltaTime = deltaSeconds; // DeltaTime is in seconds.
|
||||
}
|
||||
|
||||
readonly List<char> PressedChars = new List<char>();
|
||||
|
||||
private void UpdateImGuiInput(GameWindow wnd)
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
|
||||
MouseState MouseState = wnd.MouseState;
|
||||
KeyboardState KeyboardState = wnd.KeyboardState;
|
||||
|
||||
io.MouseDown[0] = MouseState[MouseButton.Left];
|
||||
io.MouseDown[1] = MouseState[MouseButton.Right];
|
||||
io.MouseDown[2] = MouseState[MouseButton.Middle];
|
||||
|
||||
var screenPoint = new Vector2i((int)MouseState.X, (int)MouseState.Y);
|
||||
var point = screenPoint;//wnd.PointToClient(screenPoint);
|
||||
io.MousePos = new System.Numerics.Vector2(point.X, point.Y);
|
||||
|
||||
foreach (Keys key in Enum.GetValues(typeof(Keys)))
|
||||
{
|
||||
if (key == Keys.Unknown)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
io.KeysDown[(int)key] = KeyboardState.IsKeyDown(key);
|
||||
}
|
||||
|
||||
foreach (var c in PressedChars)
|
||||
{
|
||||
io.AddInputCharacter(c);
|
||||
}
|
||||
PressedChars.Clear();
|
||||
|
||||
io.KeyCtrl = KeyboardState.IsKeyDown(Keys.LeftControl) || KeyboardState.IsKeyDown(Keys.RightControl);
|
||||
io.KeyAlt = KeyboardState.IsKeyDown(Keys.LeftAlt) || KeyboardState.IsKeyDown(Keys.RightAlt);
|
||||
io.KeyShift = KeyboardState.IsKeyDown(Keys.LeftShift) || KeyboardState.IsKeyDown(Keys.RightShift);
|
||||
io.KeySuper = KeyboardState.IsKeyDown(Keys.LeftSuper) || KeyboardState.IsKeyDown(Keys.RightSuper);
|
||||
}
|
||||
|
||||
internal void PressChar(char keyChar)
|
||||
{
|
||||
PressedChars.Add(keyChar);
|
||||
}
|
||||
|
||||
internal void MouseScroll(Vector2 offset)
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
|
||||
io.MouseWheel = offset.Y;
|
||||
io.MouseWheelH = offset.X;
|
||||
}
|
||||
|
||||
private static void SetKeyMappings()
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
io.KeyMap[(int)ImGuiKey.Tab] = (int)Keys.Tab;
|
||||
io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)Keys.Left;
|
||||
io.KeyMap[(int)ImGuiKey.RightArrow] = (int)Keys.Right;
|
||||
io.KeyMap[(int)ImGuiKey.UpArrow] = (int)Keys.Up;
|
||||
io.KeyMap[(int)ImGuiKey.DownArrow] = (int)Keys.Down;
|
||||
io.KeyMap[(int)ImGuiKey.PageUp] = (int)Keys.PageUp;
|
||||
io.KeyMap[(int)ImGuiKey.PageDown] = (int)Keys.PageDown;
|
||||
io.KeyMap[(int)ImGuiKey.Home] = (int)Keys.Home;
|
||||
io.KeyMap[(int)ImGuiKey.End] = (int)Keys.End;
|
||||
io.KeyMap[(int)ImGuiKey.Delete] = (int)Keys.Delete;
|
||||
io.KeyMap[(int)ImGuiKey.Backspace] = (int)Keys.Backspace;
|
||||
io.KeyMap[(int)ImGuiKey.Enter] = (int)Keys.Enter;
|
||||
io.KeyMap[(int)ImGuiKey.Escape] = (int)Keys.Escape;
|
||||
io.KeyMap[(int)ImGuiKey.A] = (int)Keys.A;
|
||||
io.KeyMap[(int)ImGuiKey.C] = (int)Keys.C;
|
||||
io.KeyMap[(int)ImGuiKey.V] = (int)Keys.V;
|
||||
io.KeyMap[(int)ImGuiKey.X] = (int)Keys.X;
|
||||
io.KeyMap[(int)ImGuiKey.Y] = (int)Keys.Y;
|
||||
io.KeyMap[(int)ImGuiKey.Z] = (int)Keys.Z;
|
||||
}
|
||||
|
||||
private void RenderImDrawData(ImDrawDataPtr draw_data)
|
||||
{
|
||||
if (draw_data.CmdListsCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get intial state.
|
||||
int prevVAO = GL.GetInteger(GetPName.VertexArrayBinding);
|
||||
int prevArrayBuffer = GL.GetInteger(GetPName.ArrayBufferBinding);
|
||||
int prevProgram = GL.GetInteger(GetPName.CurrentProgram);
|
||||
bool prevBlendEnabled = GL.GetBoolean(GetPName.Blend);
|
||||
bool prevScissorTestEnabled = GL.GetBoolean(GetPName.ScissorTest);
|
||||
int prevBlendEquationRgb = GL.GetInteger(GetPName.BlendEquationRgb);
|
||||
int prevBlendEquationAlpha = GL.GetInteger(GetPName.BlendEquationAlpha);
|
||||
int prevBlendFuncSrcRgb = GL.GetInteger(GetPName.BlendSrcRgb);
|
||||
int prevBlendFuncSrcAlpha = GL.GetInteger(GetPName.BlendSrcAlpha);
|
||||
int prevBlendFuncDstRgb = GL.GetInteger(GetPName.BlendDstRgb);
|
||||
int prevBlendFuncDstAlpha = GL.GetInteger(GetPName.BlendDstAlpha);
|
||||
bool prevCullFaceEnabled = GL.GetBoolean(GetPName.CullFace);
|
||||
bool prevDepthTestEnabled = GL.GetBoolean(GetPName.DepthTest);
|
||||
int prevActiveTexture = GL.GetInteger(GetPName.ActiveTexture);
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
int prevTexture2D = GL.GetInteger(GetPName.TextureBinding2D);
|
||||
Span<int> prevScissorBox = stackalloc int[4];
|
||||
unsafe
|
||||
{
|
||||
fixed (int* iptr = &prevScissorBox[0])
|
||||
{
|
||||
GL.GetInteger(GetPName.ScissorBox, iptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the element buffer (thru the VAO) so that we can resize it.
|
||||
GL.BindVertexArray(_vertexArray);
|
||||
// Bind the vertex buffer so that we can resize it.
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer);
|
||||
for (int i = 0; i < draw_data.CmdListsCount; i++)
|
||||
{
|
||||
ImDrawListPtr cmd_list = draw_data.CmdListsRange[i];
|
||||
|
||||
int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>();
|
||||
if (vertexSize > _vertexBufferSize)
|
||||
{
|
||||
int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize);
|
||||
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
|
||||
_vertexBufferSize = newSize;
|
||||
}
|
||||
|
||||
int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort);
|
||||
if (indexSize > _indexBufferSize)
|
||||
{
|
||||
int newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize);
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
|
||||
_indexBufferSize = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
Matrix4 mvp = Matrix4.CreateOrthographicOffCenter(
|
||||
0.0f,
|
||||
io.DisplaySize.X,
|
||||
io.DisplaySize.Y,
|
||||
0.0f,
|
||||
-1.0f,
|
||||
1.0f);
|
||||
|
||||
GL.UseProgram(_shader);
|
||||
GL.UniformMatrix4(_shaderProjectionMatrixLocation, false, ref mvp);
|
||||
GL.Uniform1(_shaderFontTextureLocation, 0);
|
||||
CheckGLError("Projection");
|
||||
|
||||
GL.BindVertexArray(_vertexArray);
|
||||
CheckGLError("VAO");
|
||||
|
||||
draw_data.ScaleClipRects(io.DisplayFramebufferScale);
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.Enable(EnableCap.ScissorTest);
|
||||
GL.BlendEquation(BlendEquationMode.FuncAdd);
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data.CmdListsCount; n++)
|
||||
{
|
||||
ImDrawListPtr cmd_list = draw_data.CmdListsRange[n];
|
||||
|
||||
GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf<ImDrawVert>(), cmd_list.VtxBuffer.Data);
|
||||
CheckGLError($"Data Vert {n}");
|
||||
|
||||
GL.BufferSubData(BufferTarget.ElementArrayBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data);
|
||||
CheckGLError($"Data Idx {n}");
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i];
|
||||
if (pcmd.UserCallback != IntPtr.Zero)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId);
|
||||
CheckGLError("Texture");
|
||||
|
||||
// We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates
|
||||
var clip = pcmd.ClipRect;
|
||||
GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y));
|
||||
CheckGLError("Scissor");
|
||||
|
||||
if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0)
|
||||
{
|
||||
GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(pcmd.IdxOffset * sizeof(ushort)), unchecked((int)pcmd.VtxOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort));
|
||||
}
|
||||
CheckGLError("Draw");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL.Disable(EnableCap.Blend);
|
||||
GL.Disable(EnableCap.ScissorTest);
|
||||
|
||||
// Reset state
|
||||
GL.BindTexture(TextureTarget.Texture2D, prevTexture2D);
|
||||
GL.ActiveTexture((TextureUnit)prevActiveTexture);
|
||||
GL.UseProgram(prevProgram);
|
||||
GL.BindVertexArray(prevVAO);
|
||||
GL.Scissor(prevScissorBox[0], prevScissorBox[1], prevScissorBox[2], prevScissorBox[3]);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, prevArrayBuffer);
|
||||
GL.BlendEquationSeparate((BlendEquationMode)prevBlendEquationRgb, (BlendEquationMode)prevBlendEquationAlpha);
|
||||
GL.BlendFuncSeparate(
|
||||
(BlendingFactorSrc)prevBlendFuncSrcRgb,
|
||||
(BlendingFactorDest)prevBlendFuncDstRgb,
|
||||
(BlendingFactorSrc)prevBlendFuncSrcAlpha,
|
||||
(BlendingFactorDest)prevBlendFuncDstAlpha);
|
||||
if (prevBlendEnabled) GL.Enable(EnableCap.Blend); else GL.Disable(EnableCap.Blend);
|
||||
if (prevDepthTestEnabled) GL.Enable(EnableCap.DepthTest); else GL.Disable(EnableCap.DepthTest);
|
||||
if (prevCullFaceEnabled) GL.Enable(EnableCap.CullFace); else GL.Disable(EnableCap.CullFace);
|
||||
if (prevScissorTestEnabled) GL.Enable(EnableCap.ScissorTest); else GL.Disable(EnableCap.ScissorTest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees all graphics resources used by the renderer.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GL.DeleteVertexArray(_vertexArray);
|
||||
GL.DeleteBuffer(_vertexBuffer);
|
||||
GL.DeleteBuffer(_indexBuffer);
|
||||
|
||||
GL.DeleteTexture(_fontTexture);
|
||||
GL.DeleteProgram(_shader);
|
||||
}
|
||||
|
||||
public static void LabelObject(ObjectLabelIdentifier objLabelIdent, int glObject, string name)
|
||||
{
|
||||
if (KHRDebugAvailable)
|
||||
GL.ObjectLabel(objLabelIdent, glObject, name.Length, name);
|
||||
}
|
||||
|
||||
static bool IsExtensionSupported(string name)
|
||||
{
|
||||
int n = GL.GetInteger(GetPName.NumExtensions);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
string extension = GL.GetString(StringNameIndexed.Extensions, i);
|
||||
if (extension == name) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int CreateProgram(string name, string vertexSource, string fragmentSoruce)
|
||||
{
|
||||
int program = GL.CreateProgram();
|
||||
LabelObject(ObjectLabelIdentifier.Program, program, $"Program: {name}");
|
||||
|
||||
int vertex = CompileShader(name, ShaderType.VertexShader, vertexSource);
|
||||
int fragment = CompileShader(name, ShaderType.FragmentShader, fragmentSoruce);
|
||||
|
||||
GL.AttachShader(program, vertex);
|
||||
GL.AttachShader(program, fragment);
|
||||
|
||||
GL.LinkProgram(program);
|
||||
|
||||
GL.GetProgram(program, GetProgramParameterName.LinkStatus, out int success);
|
||||
if (success == 0)
|
||||
{
|
||||
string info = GL.GetProgramInfoLog(program);
|
||||
Debug.WriteLine($"GL.LinkProgram had info log [{name}]:\n{info}");
|
||||
}
|
||||
|
||||
GL.DetachShader(program, vertex);
|
||||
GL.DetachShader(program, fragment);
|
||||
|
||||
GL.DeleteShader(vertex);
|
||||
GL.DeleteShader(fragment);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
private static int CompileShader(string name, ShaderType type, string source)
|
||||
{
|
||||
int shader = GL.CreateShader(type);
|
||||
LabelObject(ObjectLabelIdentifier.Shader, shader, $"Shader: {name}");
|
||||
|
||||
GL.ShaderSource(shader, source);
|
||||
GL.CompileShader(shader);
|
||||
|
||||
GL.GetShader(shader, ShaderParameter.CompileStatus, out int success);
|
||||
if (success == 0)
|
||||
{
|
||||
string info = GL.GetShaderInfoLog(shader);
|
||||
Debug.WriteLine($"GL.CompileShader for shader '{name}' [{type}] had info log:\n{info}");
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
public static void CheckGLError(string title)
|
||||
{
|
||||
ErrorCode error;
|
||||
int i = 1;
|
||||
while ((error = GL.GetError()) != ErrorCode.NoError)
|
||||
{
|
||||
Debug.Print($"{title} ({i++}): {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
FLogger.AppendInformation();
|
||||
FLogger.AppendText($"Mappings pulled from '{endpoint.FilePath.SubstringAfterLast("\\")}'", Constants.WHITE, true);
|
||||
}
|
||||
else
|
||||
else if (endpoint.IsValid)
|
||||
{
|
||||
var mappingsFolder = Path.Combine(UserSettings.Default.OutputDirectory, ".data");
|
||||
var mappings = _apiEndpointView.DynamicApi.GetMappings(cancellationToken, endpoint.Url, endpoint.Path);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class Cache : IDisposable
|
|||
foreach (var model in _models.Values)
|
||||
{
|
||||
if (model.IsSetup) continue;
|
||||
model.Setup();
|
||||
model.Setup(this);
|
||||
}
|
||||
}
|
||||
public void Render(Shader shader)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class Camera
|
|||
public float Speed = 1f;
|
||||
public float Near = 0.01f;
|
||||
public float Far = 100f;
|
||||
public float AspectRatio => 16f / 9f;
|
||||
public float AspectRatio = 16f / 9f;
|
||||
|
||||
public Camera(Vector3 position, Vector3 direction, float near, float far, float speed)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public class Model : IDisposable
|
|||
_morphVbo.Unbind();
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
public void Setup(Cache cache)
|
||||
{
|
||||
_handle = GL.CreateProgram();
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ public class Model : IDisposable
|
|||
|
||||
for (int section = 0; section < Sections.Length; section++)
|
||||
{
|
||||
Sections[section].Setup();
|
||||
Sections[section].Setup(cache);
|
||||
}
|
||||
|
||||
IsSetup = true;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ using CUE4Parse.UE4.Assets.Exports.Texture;
|
|||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
using CUE4Parse.UE4.Objects.Engine;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Mathematics;
|
||||
|
||||
namespace FModel.Views.Snooper;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class Section : IDisposable
|
|||
unrealMaterial.GetParams(Parameters);
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
public void Setup(Cache cache)
|
||||
{
|
||||
_handle = GL.CreateProgram();
|
||||
|
||||
|
|
@ -81,45 +81,46 @@ public class Section : IDisposable
|
|||
else
|
||||
{
|
||||
var platform = UserSettings.Default.OverridedPlatform;
|
||||
void Add(int index, UTexture2D original)
|
||||
{
|
||||
var guid = original.LightingGuid;
|
||||
if (cache.TryGetTexture(guid, out var texture))
|
||||
{
|
||||
// Anything in Parameters that is supposed to be modified will not be modified
|
||||
// eg. Metallic Roughness
|
||||
Textures[index] = texture;
|
||||
}
|
||||
else if (original.GetFirstMip() is { } mip)
|
||||
{
|
||||
byte[] data;
|
||||
if (index != 2) TextureDecoder.DecodeTexture(mip, original.Format, original.isNormalMap, platform, out data, out _);
|
||||
else SwapSpecular(original, mip, platform, out data);
|
||||
|
||||
var t = new Texture(data, mip.SizeX, mip.SizeY, original);
|
||||
cache.AddTexture(guid, t);
|
||||
Textures[index] = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Parameters.HasTopDiffuseTexture && Parameters.DiffuseColor is { A: > 0 } diffuseColor)
|
||||
{
|
||||
DiffuseColor = new Vector4(diffuseColor.R, diffuseColor.G, diffuseColor.B, diffuseColor.A);
|
||||
}
|
||||
else if (Parameters.Diffuse is UTexture2D { IsVirtual: false } diffuse)
|
||||
{
|
||||
var mip = diffuse.GetFirstMip();
|
||||
TextureDecoder.DecodeTexture(mip, diffuse.Format, diffuse.isNormalMap, platform, out var data, out var colorType);
|
||||
Textures[0] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, diffuse);
|
||||
}
|
||||
Add(0, diffuse);
|
||||
|
||||
if (Parameters.Normal is UTexture2D { IsVirtual: false } normal)
|
||||
{
|
||||
var mip = normal.GetFirstMip();
|
||||
TextureDecoder.DecodeTexture(mip, normal.Format, normal.isNormalMap, platform, out var data, out var colorType);
|
||||
Textures[1] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, normal);
|
||||
}
|
||||
Add(1, normal);
|
||||
|
||||
if (Parameters.Specular is UTexture2D { IsVirtual: false } specular)
|
||||
{
|
||||
var mip = specular.GetFirstMip();
|
||||
SwapSpecular(specular, mip, platform, out var data, out var colorType);
|
||||
Textures[2] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, specular);
|
||||
}
|
||||
Add(2, specular);
|
||||
|
||||
if (Parameters.HasTopEmissiveTexture &&
|
||||
Parameters.Emissive is UTexture2D { IsVirtual: false } emissive)
|
||||
{
|
||||
var mip = emissive.GetFirstMip();
|
||||
TextureDecoder.DecodeTexture(mip, emissive.Format, emissive.isNormalMap, platform, out var data, out var colorType);
|
||||
Textures[3] = new Texture(data, (uint) mip.SizeX, (uint) mip.SizeY, colorType, emissive);
|
||||
Add(3, emissive);
|
||||
if (Parameters.EmissiveColor is { A: > 0 } emissiveColor)
|
||||
{
|
||||
EmissionColor = new Vector4(emissiveColor.R, emissiveColor.G, emissiveColor.B, emissiveColor.A);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmissionColor = Vector4.One;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,9 +137,9 @@ public class Section : IDisposable
|
|||
/// Roughness on Green
|
||||
/// Ambient Occlusion on Red
|
||||
/// </summary>
|
||||
private void SwapSpecular(UTexture2D specular, FTexture2DMipMap mip, ETexturePlatform platform, out byte[] data, out SKColorType colorType)
|
||||
private void SwapSpecular(UTexture2D specular, FTexture2DMipMap mip, ETexturePlatform platform, out byte[] data)
|
||||
{
|
||||
TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap, platform, out data, out colorType);
|
||||
TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap, platform, out data, out _);
|
||||
|
||||
switch (_game)
|
||||
{
|
||||
|
|
@ -243,8 +244,8 @@ public class Section : IDisposable
|
|||
|
||||
shader.SetUniform("material.emissionColor", EmissionColor);
|
||||
|
||||
shader.SetUniform("material.metallic_value", Parameters.MetallicValue);
|
||||
shader.SetUniform("material.roughness_value", Parameters.RoughnessValue);
|
||||
shader.SetUniform("material.metallic_value", 1f);
|
||||
shader.SetUniform("material.roughness_value", 0f);
|
||||
|
||||
shader.SetUniform("light.ambient", _ambientLight);
|
||||
|
||||
|
|
|
|||
139
FModel/Views/Snooper/SnimGui.cs
Normal file
139
FModel/Views/Snooper/SnimGui.cs
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
using FModel.Framework;
|
||||
using ImGuiNET;
|
||||
using OpenTK.Windowing.Desktop;
|
||||
|
||||
namespace FModel.Views.Snooper;
|
||||
|
||||
public class SnimGui : IDisposable
|
||||
{
|
||||
private readonly ImGuiController _controller;
|
||||
|
||||
private readonly Vector2 _outlinerSize;
|
||||
private readonly Vector2 _outlinerPosition;
|
||||
private readonly Vector2 _propertiesSize;
|
||||
private readonly Vector2 _propertiesPosition;
|
||||
private readonly Vector2 _viewportSize;
|
||||
private readonly Vector2 _viewportPosition;
|
||||
private readonly Vector2 _textureSize;
|
||||
private readonly Vector2 _texturePosition;
|
||||
private bool _viewportFocus;
|
||||
|
||||
private const ImGuiWindowFlags _noResize = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; // delete once we have a proper docking branch
|
||||
private const ImGuiCond _firstUse = ImGuiCond.Appearing; // switch to FirstUseEver once the docking branch will not be useful anymore...
|
||||
private const uint _dockspaceId = 1337;
|
||||
|
||||
public SnimGui(int width, int height)
|
||||
{
|
||||
_controller = new ImGuiController(width, height);
|
||||
|
||||
var style = ImGui.GetStyle();
|
||||
var viewport = ImGui.GetMainViewport();
|
||||
var titleBarHeight = ImGui.GetFontSize() + style.FramePadding.Y * 2;
|
||||
|
||||
_outlinerSize = new Vector2(400, 300);
|
||||
_outlinerPosition = new Vector2(viewport.WorkSize.X - _outlinerSize.X, titleBarHeight);
|
||||
_propertiesSize = _outlinerSize with { Y = viewport.WorkSize.Y - _outlinerSize.Y - titleBarHeight };
|
||||
_propertiesPosition = new Vector2(viewport.WorkSize.X - _propertiesSize.X, _outlinerPosition.Y + _outlinerSize.Y);
|
||||
_viewportSize = _outlinerPosition with { Y = viewport.WorkSize.Y - titleBarHeight - 150 };
|
||||
_viewportPosition = new Vector2(0, titleBarHeight);
|
||||
_textureSize = _viewportSize with { Y = viewport.WorkSize.Y - _viewportSize.Y - titleBarHeight };
|
||||
_texturePosition = new Vector2(0, _viewportPosition.Y + _viewportSize.Y);
|
||||
|
||||
Theme(style);
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
ImGui.ShowDemoWindow();
|
||||
|
||||
_controller.Render();
|
||||
|
||||
ImGuiController.CheckGLError("End of frame");
|
||||
}
|
||||
|
||||
private void PushStyleCompact()
|
||||
{
|
||||
var style = ImGui.GetStyle();
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, style.FramePadding with { Y = style.FramePadding.Y * 0.6f });
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, style.ItemSpacing with { Y = style.ItemSpacing.Y * 0.6f });
|
||||
}
|
||||
|
||||
private void PopStyleCompact() => ImGui.PopStyleVar(2);
|
||||
|
||||
private void Theme(ImGuiStylePtr style)
|
||||
{
|
||||
var io = ImGui.GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags.DockingEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
|
||||
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
||||
io.ConfigDockingWithShift = true;
|
||||
|
||||
style.WindowMenuButtonPosition = ImGuiDir.Right;
|
||||
style.ScrollbarSize = 10f;
|
||||
style.FrameRounding = 3.0f;
|
||||
|
||||
style.Colors[(int) ImGuiCol.Text] = new Vector4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TextDisabled] = new Vector4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.WindowBg] = new Vector4(0.11f, 0.11f, 0.12f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.ChildBg] = new Vector4(0.15f, 0.15f, 0.19f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.PopupBg] = new Vector4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
style.Colors[(int) ImGuiCol.Border] = new Vector4(0.25f, 0.26f, 0.33f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.BorderShadow] = new Vector4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
style.Colors[(int) ImGuiCol.FrameBg] = new Vector4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||
style.Colors[(int) ImGuiCol.FrameBgHovered] = new Vector4(0.69f, 0.69f, 1.00f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.FrameBgActive] = new Vector4(0.69f, 0.69f, 1.00f, 0.39f);
|
||||
style.Colors[(int) ImGuiCol.TitleBg] = new Vector4(0.09f, 0.09f, 0.09f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TitleBgActive] = new Vector4(0.09f, 0.09f, 0.09f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TitleBgCollapsed] = new Vector4(0.05f, 0.05f, 0.05f, 0.51f);
|
||||
style.Colors[(int) ImGuiCol.MenuBarBg] = new Vector4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.ScrollbarBg] = new Vector4(0.02f, 0.02f, 0.02f, 0.53f);
|
||||
style.Colors[(int) ImGuiCol.ScrollbarGrab] = new Vector4(0.31f, 0.31f, 0.31f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.ScrollbarGrabHovered] = new Vector4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.ScrollbarGrabActive] = new Vector4(0.51f, 0.51f, 0.51f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.CheckMark] = new Vector4(0.13f, 0.42f, 0.83f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.SliderGrab] = new Vector4(0.13f, 0.42f, 0.83f, 0.78f);
|
||||
style.Colors[(int) ImGuiCol.SliderGrabActive] = new Vector4(0.13f, 0.42f, 0.83f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.Button] = new Vector4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||
style.Colors[(int) ImGuiCol.ButtonHovered] = new Vector4(0.69f, 0.69f, 1.00f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.ButtonActive] = new Vector4(0.69f, 0.69f, 1.00f, 0.39f);
|
||||
style.Colors[(int) ImGuiCol.Header] = new Vector4(0.16f, 0.16f, 0.21f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.HeaderHovered] = new Vector4(0.69f, 0.69f, 1.00f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.HeaderActive] = new Vector4(0.69f, 0.69f, 1.00f, 0.39f);
|
||||
style.Colors[(int) ImGuiCol.Separator] = new Vector4(0.43f, 0.43f, 0.50f, 0.50f);
|
||||
style.Colors[(int) ImGuiCol.SeparatorHovered] = new Vector4(0.10f, 0.40f, 0.75f, 0.78f);
|
||||
style.Colors[(int) ImGuiCol.SeparatorActive] = new Vector4(0.10f, 0.40f, 0.75f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.ResizeGrip] = new Vector4(0.13f, 0.42f, 0.83f, 0.39f);
|
||||
style.Colors[(int) ImGuiCol.ResizeGripHovered] = new Vector4(0.12f, 0.41f, 0.81f, 0.78f);
|
||||
style.Colors[(int) ImGuiCol.ResizeGripActive] = new Vector4(0.12f, 0.41f, 0.81f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.Tab] = new Vector4(0.15f, 0.15f, 0.19f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TabHovered] = new Vector4(0.35f, 0.35f, 0.41f, 0.80f);
|
||||
style.Colors[(int) ImGuiCol.TabActive] = new Vector4(0.23f, 0.24f, 0.29f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TabUnfocused] = new Vector4(0.15f, 0.15f, 0.15f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TabUnfocusedActive] = new Vector4(0.14f, 0.26f, 0.42f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.DockingPreview] = new Vector4(0.26f, 0.59f, 0.98f, 0.70f);
|
||||
style.Colors[(int) ImGuiCol.DockingEmptyBg] = new Vector4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.PlotLines] = new Vector4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.PlotLinesHovered] = new Vector4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.PlotHistogram] = new Vector4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.PlotHistogramHovered] = new Vector4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TableHeaderBg] = new Vector4(0.09f, 0.09f, 0.09f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.TableBorderStrong] = new Vector4(0.69f, 0.69f, 1.00f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.TableBorderLight] = new Vector4(0.69f, 0.69f, 1.00f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.TableRowBg] = new Vector4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
style.Colors[(int) ImGuiCol.TableRowBgAlt] = new Vector4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||
style.Colors[(int) ImGuiCol.TextSelectedBg] = new Vector4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
style.Colors[(int) ImGuiCol.DragDropTarget] = new Vector4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
style.Colors[(int) ImGuiCol.NavHighlight] = new Vector4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||
style.Colors[(int) ImGuiCol.NavWindowingHighlight] = new Vector4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
style.Colors[(int) ImGuiCol.NavWindowingDimBg] = new Vector4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
style.Colors[(int) ImGuiCol.ModalWindowDimBg] = new Vector4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
}
|
||||
|
||||
public void Update(GameWindow wnd, float deltaSeconds) => _controller.Update(wnd, deltaSeconds);
|
||||
public void WindowResized(int width, int height) => _controller.WindowResized(width, height);
|
||||
public void Dispose() => _controller.Dispose();
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ public class Snooper : GameWindow
|
|||
private readonly Skybox _skybox;
|
||||
private readonly Grid _grid;
|
||||
private readonly Renderer _renderer;
|
||||
private readonly SnimGui _gui;
|
||||
|
||||
private Camera _camera;
|
||||
private float _previousSpeed;
|
||||
|
|
@ -28,6 +29,7 @@ public class Snooper : GameWindow
|
|||
_skybox = new Skybox();
|
||||
_grid = new Grid();
|
||||
_renderer = new Renderer();
|
||||
_gui = new SnimGui(ClientSize.X, ClientSize.Y);
|
||||
_init = false;
|
||||
}
|
||||
|
||||
|
|
@ -96,6 +98,7 @@ public class Snooper : GameWindow
|
|||
if (!IsVisible)
|
||||
return;
|
||||
|
||||
_gui.Update(this, (float)args.Time);
|
||||
ClearWhatHasBeenDrawn(); // in main window
|
||||
|
||||
// _framebuffer.Bind(); // switch to dedicated window
|
||||
|
|
@ -104,6 +107,7 @@ public class Snooper : GameWindow
|
|||
_skybox.Render(_camera);
|
||||
_grid.Render(_camera);
|
||||
_renderer.Render(_camera);
|
||||
_gui.Render();
|
||||
|
||||
// _framebuffer.BindMsaa();
|
||||
// _framebuffer.Bind(0); // switch back to main window
|
||||
|
|
@ -165,6 +169,18 @@ public class Snooper : GameWindow
|
|||
base.OnResize(e);
|
||||
|
||||
GL.Viewport(0, 0, Size.X, Size.Y);
|
||||
// _camera.AspectRatio = Size.X / (float)Size.Y;
|
||||
|
||||
_camera.AspectRatio = Size.X / (float)Size.Y;
|
||||
_gui.WindowResized(ClientSize.X, ClientSize.Y);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
_skybox?.Dispose();
|
||||
_grid?.Dispose();
|
||||
_renderer?.Dispose();
|
||||
_gui?.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class Texture : IDisposable
|
|||
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _handle, 0);
|
||||
}
|
||||
|
||||
public unsafe Texture(int width, int height) : this(TextureType.Framebuffer)
|
||||
public Texture(int width, int height) : this(TextureType.Framebuffer)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
|
@ -62,7 +62,7 @@ public class Texture : IDisposable
|
|||
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _handle, 0);
|
||||
}
|
||||
|
||||
public unsafe Texture(byte[] data, uint width, uint height, SKColorType colorType, UTexture2D texture2D) : this(TextureType.Normal)
|
||||
public Texture(byte[] data, int width, int height, UTexture2D texture2D) : this(TextureType.Normal)
|
||||
{
|
||||
Type = texture2D.ExportType;
|
||||
Name = texture2D.Name;
|
||||
|
|
@ -70,8 +70,8 @@ public class Texture : IDisposable
|
|||
Format = texture2D.Format;
|
||||
ImportedWidth = texture2D.ImportedSize.X;
|
||||
ImportedHeight = texture2D.ImportedSize.Y;
|
||||
Width = (int) width;
|
||||
Height = (int) height;
|
||||
Width = width;
|
||||
Height = height;
|
||||
Bind(TextureUnit.Texture0);
|
||||
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, Width, Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data);
|
||||
|
|
@ -83,7 +83,7 @@ public class Texture : IDisposable
|
|||
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
|
||||
}
|
||||
|
||||
public unsafe Texture(string[] textures) : this(TextureType.Cubemap)
|
||||
public Texture(string[] textures) : this(TextureType.Cubemap)
|
||||
{
|
||||
Bind(TextureUnit.Texture0);
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ public class Texture : IDisposable
|
|||
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
|
||||
}
|
||||
|
||||
public unsafe Texture(uint width, uint height, IntPtr data) : this(TextureType.Normal)
|
||||
public Texture(uint width, uint height, IntPtr data) : this(TextureType.Normal)
|
||||
{
|
||||
Width = (int) width;
|
||||
Height = (int) height;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user