diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index d2590bc8..bf377057 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -79,7 +79,7 @@ private async void OnLoaded(object sender, RoutedEventArgs e) #if DEBUG await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.Extract( - "FortniteGame/Content/Environments/Props/Winter/Meshes/SM_Garland_Merge.uasset")); + "FortniteGame/Content/Environments/Props/Winter/Meshes/S_Sled.uasset")); #endif } diff --git a/FModel/Views/Snooper/Shader.cs b/FModel/Views/Snooper/Shader.cs index 4cf96dc5..5c39376e 100644 --- a/FModel/Views/Snooper/Shader.cs +++ b/FModel/Views/Snooper/Shader.cs @@ -25,13 +25,9 @@ public class Shader : IDisposable void main() { - //Multiplying our uniform with the vertex position, the multiplication order here does matter. gl_Position = uProjection * uView * uModel * vec4(vPos, 1.0); - //We want to know the fragment's position in World space, so we multiply ONLY by uModel and not uView or uProjection fPos = vec3(uModel * vec4(vPos, 1.0)); - //The Normal needs to be in World space too, but needs to account for Scaling of the object fNormal = mat3(transpose(inverse(uModel))) * vNormal; - //Pass the texture coordinates straight through to the fragment shader fTexCoords = vTexCoords; } "; @@ -43,14 +39,22 @@ void main() in vec3 fPos; in vec2 fTexCoords; +struct Material { + sampler2D albedo; + sampler2D normal; + sampler2D specular; + sampler2D metallic; + sampler2D emissive; +}; + +uniform Material material; uniform vec3 viewPos; out vec4 FragColor; void main() { - vec3 viewDirection = normalize(viewPos - fPos); - FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); + FragColor = texture(material.albedo, fTexCoords); } "; diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index 323c33ec..d7ebecb7 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -2,8 +2,11 @@ using System.Linq; using System.Numerics; using CUE4Parse.UE4.Assets.Exports; +using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Assets.Exports.StaticMesh; +using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse_Conversion.Meshes; +using CUE4Parse_Conversion.Textures; using Silk.NET.Input; using Silk.NET.Maths; using Silk.NET.OpenGL; @@ -23,6 +26,10 @@ public class Snooper private BufferObject _vbo; private VertexArrayObject _vao; private Shader _shader; + private CMaterialParams _params; + + private Texture _albedoMap; + private Texture _normalMap; private uint[] _indices; private float[] _vertices; @@ -30,20 +37,21 @@ public class Snooper public int Width { get; } public int Height { get; } - private const double _ratio = .75; - private const int _vertexSize = 8; // just so we don't have to do .Length + private const int _vertexSize = 8; // Position + Normals + UV private const uint _faceSize = 3; // just so we don't have to do .Length private readonly uint[] _facesIndex = { 1, 0, 2 }; public Snooper(UObject export) { + const double ratio = .6; var x = System.Windows.SystemParameters.MaximizedPrimaryScreenWidth; var y = System.Windows.SystemParameters.MaximizedPrimaryScreenHeight; - Width = Convert.ToInt32(x * _ratio); - Height = Convert.ToInt32(y * _ratio); + Width = Convert.ToInt32(x * ratio); + Height = Convert.ToInt32(y * ratio); var options = WindowOptions.Default; options.Size = new Vector2D(Width, Height); + options.Position = new Vector2D(Width, Height); options.Title = "Snooper"; _window = Window.Create(options); @@ -64,7 +72,8 @@ public Snooper(UObject export) { foreach (var f in _facesIndex) { - var index = section.FirstIndex + face * _faceSize + f; + var i = face * _faceSize + f; + var index = section.FirstIndex + i; var indice = mesh.LODs[0].Indices.Value[index]; var vert = mesh.LODs[0].Verts[indice]; @@ -77,9 +86,15 @@ public Snooper(UObject export) _vertices[index * _vertexSize + 6] = vert.UV.U; _vertices[index * _vertexSize + 7] = vert.UV.V; - _indices[index] = face * _faceSize + f; + _indices[index] = i; } } + + _params = new CMaterialParams(); + if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial) + { + unrealMaterial.GetParams(_params); + } } break; } @@ -118,6 +133,12 @@ private void OnLoad() _shader = new Shader(_gl); _camera = new Camera(Vector3.UnitZ * 6, Vector3.UnitZ * -1, Vector3.UnitY, Width / Height); + + if (_params.Diffuse is UTexture2D { IsVirtual: false } diffuse && diffuse.GetFirstMip() is { } mip) + { + TextureDecoder.DecodeTexture(mip, diffuse.Format, diffuse.isNormalMap, out var data, out _); + _albedoMap = new Texture(_gl, data, (uint) mip.SizeX, (uint) mip.SizeY); + } } private unsafe void OnRender(double deltaTime) @@ -127,17 +148,23 @@ private unsafe void OnRender(double deltaTime) _vao.Bind(); _shader.Use(); + _albedoMap.Bind(TextureUnit.Texture0); + _shader.SetUniform("uModel", Matrix4x4.Identity); _shader.SetUniform("uView", _camera.GetViewMatrix()); _shader.SetUniform("uProjection", _camera.GetProjectionMatrix()); // _shader.SetUniform("viewPos", _camera.Position); + //Configure the materials variables. + _shader.SetUniform("material.albedo", 0); + _gl.DrawElements(PrimitiveType.Triangles, (uint) _indices.Length, DrawElementsType.UnsignedInt, null); } private void OnUpdate(double deltaTime) { - var moveSpeed = 5f * (float) deltaTime; + var speed = _keyboard.IsKeyPressed(Key.ShiftLeft) ? 5f : 2.5f; + var moveSpeed = speed * (float) deltaTime; if (_keyboard.IsKeyPressed(Key.W)) { _camera.Position += moveSpeed * _camera.Front; @@ -154,6 +181,14 @@ private void OnUpdate(double deltaTime) { _camera.Position += Vector3.Normalize(Vector3.Cross(_camera.Front, _camera.Up)) * moveSpeed; } + if (_keyboard.IsKeyPressed(Key.E)) + { + _camera.Position += moveSpeed * _camera.Up; + } + if (_keyboard.IsKeyPressed(Key.Q)) + { + _camera.Position -= moveSpeed * _camera.Up; + } } private void OnMouseMove(IMouse mouse, Vector2 position) diff --git a/FModel/Views/Snooper/Texture.cs b/FModel/Views/Snooper/Texture.cs index ed843e73..d8d00013 100644 --- a/FModel/Views/Snooper/Texture.cs +++ b/FModel/Views/Snooper/Texture.cs @@ -8,12 +8,12 @@ public class Texture : IDisposable private uint _handle; private GL _gl; - public unsafe Texture(GL gl, Span data, uint width, uint height) + public unsafe Texture(GL gl, byte[] data, uint width, uint height) { _gl = gl; _handle = _gl.GenTexture(); - Bind(); + Bind(TextureUnit.Texture0); fixed (void* d = &data[0]) { @@ -33,7 +33,7 @@ private void SetParameters() _gl.GenerateMipmap(TextureTarget.Texture2D); } - public void Bind(TextureUnit textureSlot = TextureUnit.Texture0) + public void Bind(TextureUnit textureSlot) { _gl.ActiveTexture(textureSlot); _gl.BindTexture(TextureTarget.Texture2D, _handle);