diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 1011b571fd..cebceefb06 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -680,6 +680,7 @@ GLAPI void glRecti(GLint x1, GLint y1, GLint x2, GLint y2); GLAPI void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params); GLAPI void glPointSize(GLfloat size); GLAPI void glClipPlane(GLenum plane, GLdouble const* equation); +GLAPI void glArrayElement(GLint i); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLContext.cpp b/Userland/Libraries/LibGL/GLContext.cpp index 1e72994c68..504eb6918d 100644 --- a/Userland/Libraries/LibGL/GLContext.cpp +++ b/Userland/Libraries/LibGL/GLContext.cpp @@ -2308,6 +2308,41 @@ void GLContext::gl_draw_pixels(GLsizei width, GLsizei height, GLenum format, GLe } } +void GLContext::gl_array_element(GLint i) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_array_element, i); + RETURN_WITH_ERROR_IF(i < 0, GL_INVALID_VALUE); + + // This is effectively the same as `gl_draw_elements`, except we only output a single + // vertex (this is done between a `gl_begin/end` call) that is to be rendered. + if (!m_client_side_vertex_array_enabled) + return; + + 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); + 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 }; + read_from_vertex_attribute_pointer(m_client_tex_coord_pointer[t], i, tex_coords); + gl_multi_tex_coord(GL_TEXTURE0 + t, tex_coords[0], tex_coords[1], tex_coords[2], tex_coords[3]); + } + } + + if (m_client_side_normal_array_enabled) { + float normal[3]; + read_from_vertex_attribute_pointer(m_client_normal_pointer, i, normal); + gl_normal(normal[0], normal[1], normal[2]); + } + + float vertex[4] { 0, 0, 0, 1 }; + read_from_vertex_attribute_pointer(m_client_vertex_pointer, i, vertex); + gl_vertex(vertex[0], vertex[1], vertex[2], vertex[3]); +} + void GLContext::gl_depth_range(GLdouble min, GLdouble max) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_depth_range, min, max); diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 1afba6bd73..47c575479f 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -158,6 +158,7 @@ public: void gl_get_light(GLenum light, GLenum pname, void* params, GLenum type); void gl_get_material(GLenum face, GLenum pname, void* params, GLenum type); void gl_clip_plane(GLenum plane, GLdouble const* equation); + void gl_array_element(GLint i); void present(); private: @@ -400,7 +401,8 @@ private: decltype(&GLContext::gl_materialiv), decltype(&GLContext::gl_color_material), decltype(&GLContext::gl_get_light), - decltype(&GLContext::gl_clip_plane)>; + decltype(&GLContext::gl_clip_plane), + decltype(&GLContext::gl_array_element)>; using ExtraSavedArguments = Variant< FloatMatrix4x4>; diff --git a/Userland/Libraries/LibGL/GLVertexArrays.cpp b/Userland/Libraries/LibGL/GLVertexArrays.cpp index 3dea1ade54..985ba463b4 100644 --- a/Userland/Libraries/LibGL/GLVertexArrays.cpp +++ b/Userland/Libraries/LibGL/GLVertexArrays.cpp @@ -33,3 +33,8 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, void const* indices { g_gl_context->gl_draw_elements(mode, count, type, indices); } + +void glArrayElement(GLint i) +{ + g_gl_context->gl_array_element(i); +}