summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorJelle Raaijmakers <jelle@gmta.nl>2021-12-30 00:27:17 +0100
committerAndreas Kling <kling@serenityos.org>2021-12-30 14:24:29 +0100
commit3a5f69b6f387464f4e9d625fc8a05e98eccaf80e (patch)
treea672701075a4149d1a604c2125d6e515dc770908 /Userland
parente056cf7e3f32b81ee7d10646a9bbab3fd9692c74 (diff)
downloadserenity-3a5f69b6f387464f4e9d625fc8a05e98eccaf80e.zip
LibGL+LibSoftGPU: Implement normalization of normals
* LibGL now supports the `GL_NORMALIZE` capability * LibSoftGPU transforms and normalizes the vertices' normals Normals are heavily used in texture coordinate generation, to be implemented in a future commit.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp23
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h1
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.cpp14
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.h4
4 files changed, 38 insertions, 4 deletions
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp
index b8eeadc0a5..2e32999aaf 100644
--- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp
+++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp
@@ -280,7 +280,16 @@ void SoftwareGLContext::gl_end()
VERIFY_NOT_REACHED();
}
- m_rasterizer.draw_primitives(primitive_type, m_projection_matrix * m_model_view_matrix, m_texture_matrix, m_vertex_list, enabled_texture_units);
+ // 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 normal_transform = FloatMatrix3x3(
+ mv_elements[0][0], mv_elements[0][1], mv_elements[0][2],
+ mv_elements[1][0], mv_elements[1][1], mv_elements[1][2],
+ mv_elements[2][0], mv_elements[2][1], mv_elements[2][2]);
+ normal_transform = normal_transform.inverse();
+
+ m_rasterizer.draw_primitives(primitive_type, m_projection_matrix * m_model_view_matrix, normal_transform, m_texture_matrix, m_vertex_list, enabled_texture_units);
m_vertex_list.clear_with_capacity();
}
@@ -619,6 +628,11 @@ void SoftwareGLContext::gl_enable(GLenum capability)
case GL_LIGHTING:
m_lighting_enabled = true;
break;
+ case GL_NORMALIZE:
+ m_normalize = true;
+ rasterizer_options.normalization_enabled = true;
+ update_rasterizer_options = true;
+ break;
case GL_SCISSOR_TEST:
rasterizer_options.scissor_enabled = true;
update_rasterizer_options = true;
@@ -690,6 +704,11 @@ void SoftwareGLContext::gl_disable(GLenum capability)
case GL_LIGHTING:
m_lighting_enabled = false;
break;
+ case GL_NORMALIZE:
+ m_normalize = false;
+ rasterizer_options.normalization_enabled = false;
+ update_rasterizer_options = true;
+ break;
case GL_SCISSOR_TEST:
rasterizer_options.scissor_enabled = false;
update_rasterizer_options = true;
@@ -742,6 +761,8 @@ GLboolean SoftwareGLContext::gl_is_enabled(GLenum capability)
return rasterizer_options.fog_enabled;
case GL_LIGHTING:
return m_lighting_enabled;
+ case GL_NORMALIZE:
+ return m_normalize;
case GL_SCISSOR_TEST:
return rasterizer_options.scissor_enabled;
case GL_STENCIL_TEST:
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h
index 8ef1452fce..0b893c3a92 100644
--- a/Userland/Libraries/LibGL/SoftwareGLContext.h
+++ b/Userland/Libraries/LibGL/SoftwareGLContext.h
@@ -206,6 +206,7 @@ private:
GLclampf m_alpha_test_ref_value = 0;
bool m_dither_enabled { true };
+ bool m_normalize { false };
// Stencil configuration
bool m_stencil_test_enabled { false };
diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp
index a3715f7c70..3602dc5752 100644
--- a/Userland/Libraries/LibSoftGPU/Device.cpp
+++ b/Userland/Libraries/LibSoftGPU/Device.cpp
@@ -524,7 +524,8 @@ DeviceInfo Device::info() const
};
}
-void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& transform, FloatMatrix4x4 const& texture_matrix, Vector<Vertex> const& vertices, Vector<size_t> const& enabled_texture_units)
+void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& transform, FloatMatrix3x3 const& normal_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):
@@ -675,8 +676,17 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
continue;
}
- if (area > 0) {
+ if (area > 0)
swap(triangle.vertices[0], triangle.vertices[1]);
+
+ // Transform normals
+ triangle.vertices[0].normal = normal_transform * triangle.vertices[0].normal;
+ triangle.vertices[1].normal = normal_transform * triangle.vertices[1].normal;
+ triangle.vertices[2].normal = normal_transform * triangle.vertices[2].normal;
+ if (m_options.normalization_enabled) {
+ triangle.vertices[0].normal.normalize();
+ triangle.vertices[1].normal.normalize();
+ triangle.vertices[2].normal.normalize();
}
submit_triangle(triangle, enabled_texture_units);
diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h
index 67c6b83569..1f8ebbdae5 100644
--- a/Userland/Libraries/LibSoftGPU/Device.h
+++ b/Userland/Libraries/LibSoftGPU/Device.h
@@ -10,6 +10,7 @@
#include <AK/NonnullRefPtr.h>
#include <AK/OwnPtr.h>
#include <LibGfx/Bitmap.h>
+#include <LibGfx/Matrix3x3.h>
#include <LibGfx/Matrix4x4.h>
#include <LibGfx/Rect.h>
#include <LibGfx/Vector4.h>
@@ -47,6 +48,7 @@ struct RasterizerOptions {
float fog_start { 0.0f };
float fog_end { 1.0f };
bool scissor_enabled { false };
+ bool normalization_enabled { false };
Gfx::IntRect scissor_box;
bool enable_color_write { true };
float depth_offset_factor { 0 };
@@ -65,7 +67,7 @@ public:
DeviceInfo info() const;
- void draw_primitives(PrimitiveType, FloatMatrix4x4 const& transform, FloatMatrix4x4 const& texture_matrix, Vector<Vertex> const& vertices, Vector<size_t> const& enabled_texture_units);
+ void draw_primitives(PrimitiveType, FloatMatrix4x4 const& transform, FloatMatrix3x3 const& normal_transform, FloatMatrix4x4 const& texture_transform, Vector<Vertex> const& vertices, Vector<size_t> const& enabled_texture_units);
void resize(const Gfx::IntSize& min_size);
void clear_color(const FloatVector4&);
void clear_depth(float);