From 287f33165e84b212ada2e572e92b7adb6a56a370 Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Sun, 6 Mar 2022 01:43:42 +0100 Subject: [PATCH] LibGL: Implement `glNormalPointer` Used for `glDrawArrays` and `glDrawElements`, the normal pointer should point to sets of X, Y and Z values. --- .../Libraries/LibGL/SoftwareGLContext.cpp | 117 +++++++++--------- Userland/Libraries/LibGL/SoftwareGLContext.h | 10 +- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 03166c5e8e..8f4029fac1 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -2008,18 +2008,18 @@ void SoftwareGLContext::gl_enable_client_state(GLenum cap) RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); switch (cap) { - case GL_VERTEX_ARRAY: - m_client_side_vertex_array_enabled = true; - break; - case GL_COLOR_ARRAY: m_client_side_color_array_enabled = true; break; - + case GL_NORMAL_ARRAY: + m_client_side_normal_array_enabled = true; + break; case GL_TEXTURE_COORD_ARRAY: m_client_side_texture_coord_array_enabled[m_client_active_texture] = true; break; - + case GL_VERTEX_ARRAY: + m_client_side_vertex_array_enabled = true; + break; default: RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); } @@ -2030,18 +2030,18 @@ void SoftwareGLContext::gl_disable_client_state(GLenum cap) RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); switch (cap) { - case GL_VERTEX_ARRAY: - m_client_side_vertex_array_enabled = false; - break; - case GL_COLOR_ARRAY: m_client_side_color_array_enabled = false; break; - + case GL_NORMAL_ARRAY: + m_client_side_normal_array_enabled = false; + break; case GL_TEXTURE_COORD_ARRAY: m_client_side_texture_coord_array_enabled[m_client_active_texture] = false; break; - + case GL_VERTEX_ARRAY: + m_client_side_vertex_array_enabled = false; + break; default: RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); } @@ -2057,57 +2057,54 @@ void SoftwareGLContext::gl_client_active_texture(GLenum target) void SoftwareGLContext::gl_vertex_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) { RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF(!(size == 2 || size == 3 || size == 4), GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); - m_client_vertex_pointer.size = size; - m_client_vertex_pointer.type = type; - m_client_vertex_pointer.stride = stride; - m_client_vertex_pointer.pointer = pointer; + m_client_vertex_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer }; } void SoftwareGLContext::gl_color_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) { RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF(!(size == 3 || size == 4), GL_INVALID_VALUE); - - RETURN_WITH_ERROR_IF(!(type == GL_BYTE - || type == GL_UNSIGNED_BYTE - || type == GL_SHORT - || type == GL_UNSIGNED_SHORT - || type == GL_INT - || type == GL_UNSIGNED_INT - || type == GL_FLOAT - || type == GL_DOUBLE), + RETURN_WITH_ERROR_IF(type != GL_BYTE + && type != GL_UNSIGNED_BYTE + && type != GL_SHORT + && type != GL_UNSIGNED_SHORT + && type != GL_INT + && type != GL_UNSIGNED_INT + && type != GL_FLOAT + && type != GL_DOUBLE, GL_INVALID_ENUM); - RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); - m_client_color_pointer.size = size; - m_client_color_pointer.type = type; - m_client_color_pointer.stride = stride; - m_client_color_pointer.pointer = pointer; + m_client_color_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer }; } void SoftwareGLContext::gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) { RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF(!(size == 1 || size == 2 || size == 3 || size == 4), GL_INVALID_VALUE); - RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM); - RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); auto& tex_coord_pointer = m_client_tex_coord_pointer[m_client_active_texture]; + tex_coord_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer }; +} - tex_coord_pointer.size = size; - tex_coord_pointer.type = type; - tex_coord_pointer.stride = stride; - tex_coord_pointer.pointer = pointer; +void SoftwareGLContext::gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer) +{ + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(type != GL_BYTE + && type != GL_SHORT + && type != GL_INT + && type != GL_FLOAT + && type != GL_DOUBLE, + GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); + + m_client_normal_pointer = { .size = 3, .type = type, .stride = stride, .pointer = pointer }; } void SoftwareGLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param) @@ -2160,6 +2157,12 @@ void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count) auto last = first + count; gl_begin(mode); for (int i = first; i < last; i++) { + if (m_client_side_color_array_enabled) { + float color[4] { 0, 0, 0, 1 }; + read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); + gl_color(color[0], color[1], color[2], color[3]); + } + for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) { if (m_client_side_texture_coord_array_enabled[t]) { float tex_coords[4] { 0, 0, 0, 0 }; @@ -2168,10 +2171,10 @@ void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count) } } - if (m_client_side_color_array_enabled) { - float color[4] { 0, 0, 0, 1 }; - read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); - gl_color(color[0], color[1], color[2], color[3]); + if (m_client_side_normal_array_enabled) { + float normal[3]; + read_from_vertex_attribute_pointer(m_client_normal_pointer, i, normal, false); + gl_normal(normal[0], normal[1], normal[2]); } float vertex[4] { 0, 0, 0, 1 }; @@ -2221,6 +2224,12 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type break; } + if (m_client_side_color_array_enabled) { + float color[4] { 0, 0, 0, 1 }; + read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); + gl_color(color[0], color[1], color[2], color[3]); + } + for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) { if (m_client_side_texture_coord_array_enabled[t]) { float tex_coords[4] { 0, 0, 0, 0 }; @@ -2229,10 +2238,10 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type } } - if (m_client_side_color_array_enabled) { - float color[4] { 0, 0, 0, 1 }; - read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); - gl_color(color[0], color[1], color[2], color[3]); + if (m_client_side_normal_array_enabled) { + float normal[3]; + read_from_vertex_attribute_pointer(m_client_normal_pointer, i, normal, false); + gl_normal(normal[0], normal[1], normal[2]); } float vertex[4] { 0, 0, 0, 1 }; @@ -2734,20 +2743,6 @@ void SoftwareGLContext::gl_normal(GLfloat nx, GLfloat ny, GLfloat nz) m_current_vertex_normal = { nx, ny, nz }; } -void SoftwareGLContext::gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer) -{ - RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF(type != GL_BYTE - && type != GL_SHORT - && type != GL_INT - && type != GL_FLOAT - && type != GL_DOUBLE, - GL_INVALID_ENUM); - RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); - - dbgln_if(GL_DEBUG, "gl_normal_pointer({:#x}, {}, {:p}): unimplemented", type, stride, pointer); -} - void SoftwareGLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_raster_pos, x, y, z, w); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 02395e54c9..7fd835ab4f 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -211,9 +211,9 @@ private: float m_clear_depth { 1.f }; u8 m_clear_stencil { 0 }; - FloatVector4 m_current_vertex_color = { 1.0f, 1.0f, 1.0f, 1.0f }; + FloatVector4 m_current_vertex_color { 1.0f, 1.0f, 1.0f, 1.0f }; Vector m_current_vertex_tex_coord; - FloatVector3 m_current_vertex_normal = { 0.0f, 0.0f, 1.0f }; + FloatVector3 m_current_vertex_normal { 0.0f, 0.0f, 1.0f }; Vector m_vertex_list; @@ -261,10 +261,11 @@ private: GLenum m_current_draw_buffer = GL_BACK; // Client side arrays - bool m_client_side_vertex_array_enabled = false; - bool m_client_side_color_array_enabled = false; + bool m_client_side_vertex_array_enabled { false }; + bool m_client_side_color_array_enabled { false }; Vector m_client_side_texture_coord_array_enabled; size_t m_client_active_texture = 0; + bool m_client_side_normal_array_enabled { false }; NonnullRefPtr m_frontbuffer; @@ -413,6 +414,7 @@ private: VertexAttribPointer m_client_vertex_pointer; VertexAttribPointer m_client_color_pointer; Vector m_client_tex_coord_pointer; + VertexAttribPointer m_client_normal_pointer; u8 m_pack_alignment { 4 }; GLsizei m_unpack_row_length { 0 };