summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelle Raaijmakers <jelle@gmta.nl>2022-03-23 14:07:27 +0100
committerBrian Gianforcaro <b.gianfo@gmail.com>2022-03-27 09:19:43 -0700
commit8a3242cb83a0031cba8556e2d21cc8230088b432 (patch)
tree67a1ccd07506a81671c4a72d3f8e0c2b834b97a2
parent74de8e4224e1e883dac71c399b86bfd499f811c8 (diff)
downloadserenity-8a3242cb83a0031cba8556e2d21cc8230088b432.zip
LibGL+LibSoftGPU+LibGfx: Reimplement normal transformation
We now support generating top-left submatrices from a `Gfx::Matrix` and we move the normal transformation calculation into `SoftGPU::Device`. No functional changes.
-rw-r--r--Userland/Libraries/LibGL/GLContext.cpp11
-rw-r--r--Userland/Libraries/LibGfx/Matrix.h14
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.cpp9
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.h2
4 files changed, 22 insertions, 14 deletions
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<size_t N, typename T>
class Matrix {
+ template<size_t U, typename V>
+ friend class Matrix;
+
public:
static constexpr size_t Size = N;
@@ -173,6 +176,17 @@ public:
return result;
}
+ template<size_t U>
+ [[nodiscard]] constexpr Matrix<U, T> submatrix_from_topleft() const requires(U > 0 && U < N)
+ {
+ Matrix<U, T> 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<Vertex> const& vertices,
- Vector<size_t> 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<Vertex> const& vertices, Vector<size_t> 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<Vertex> const& vertices, Vector<size_t> const& enabled_texture_units);
+ void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector<Vertex> const& vertices, Vector<size_t> const& enabled_texture_units);
void resize(Gfx::IntSize const& min_size);
void clear_color(FloatVector4 const&);
void clear_depth(DepthType);