diff --git a/Userland/Libraries/LibGL/GLContext.cpp b/Userland/Libraries/LibGL/GLContext.cpp index 009c765436..0c0246f25d 100644 --- a/Userland/Libraries/LibGL/GLContext.cpp +++ b/Userland/Libraries/LibGL/GLContext.cpp @@ -379,16 +379,7 @@ void GLContext::gl_end() VERIFY_NOT_REACHED(); } - // Set up normals transform by taking the upper left 3x3 elements from the model view matrix - // See section 2.11.3 of the OpenGL 1.5 spec - auto const& mv_elements = m_model_view_matrix.elements(); - auto const model_view_transposed = FloatMatrix3x3( - mv_elements[0][0], mv_elements[1][0], mv_elements[2][0], - mv_elements[0][1], mv_elements[1][1], mv_elements[2][1], - mv_elements[0][2], mv_elements[1][2], mv_elements[2][2]); - auto const& normal_transform = model_view_transposed.inverse(); - - m_rasterizer.draw_primitives(primitive_type, m_model_view_matrix, normal_transform, m_projection_matrix, m_texture_matrix, m_vertex_list, enabled_texture_units); + m_rasterizer.draw_primitives(primitive_type, m_model_view_matrix, m_projection_matrix, m_texture_matrix, m_vertex_list, enabled_texture_units); m_vertex_list.clear_with_capacity(); } diff --git a/Userland/Libraries/LibGfx/Matrix.h b/Userland/Libraries/LibGfx/Matrix.h index 2e251de293..78be55f48f 100644 --- a/Userland/Libraries/LibGfx/Matrix.h +++ b/Userland/Libraries/LibGfx/Matrix.h @@ -13,6 +13,9 @@ namespace Gfx { template class Matrix { + template + friend class Matrix; + public: static constexpr size_t Size = N; @@ -173,6 +176,17 @@ public: return result; } + template + [[nodiscard]] constexpr Matrix submatrix_from_topleft() const requires(U > 0 && U < N) + { + Matrix result; + for (size_t i = 0; i < U; ++i) { + for (size_t j = 0; j < U; ++j) + result.m_elements[i][j] = m_elements[i][j]; + } + return result; + } + private: T m_elements[N][N]; }; diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index f5380bb78d..3db74a188a 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -639,9 +639,8 @@ static void generate_texture_coordinates(Vertex& vertex, RasterizerOptions const } } -void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix3x3 const& normal_transform, - FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector const& vertices, - Vector const& enabled_texture_units) +void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, + FloatMatrix4x4 const& texture_transform, Vector const& vertices, Vector const& enabled_texture_units) { // At this point, the user has effectively specified that they are done with defining the geometry // of what they want to draw. We now need to do a few things (https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview): @@ -716,6 +715,10 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& } } + // Set up normals transform by taking the upper left 3x3 elements from the model view matrix + // See section 2.11.3 of the OpenGL 1.5 spec + auto normal_transform = model_view_transform.submatrix_from_topleft<3>().transpose().inverse(); + // Now let's transform each triangle and send that to the GPU auto const viewport = m_options.viewport; auto const viewport_half_width = viewport.width() / 2.0f; diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index af5e1cb0c5..aefc01aa96 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -115,7 +115,7 @@ public: DeviceInfo info() const; - void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix3x3 const& normal_transform, FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector const& vertices, Vector const& enabled_texture_units); + void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector const& vertices, Vector const& enabled_texture_units); void resize(Gfx::IntSize const& min_size); void clear_color(FloatVector4 const&); void clear_depth(DepthType);