diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2021-08-13 15:37:38 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-14 12:49:29 +0200 |
commit | 949d27f21bf8de89023427e3da342091041cb351 (patch) | |
tree | 9da9e2e02909ff9e18dc5a5dce3f6d2181c9e5f7 /Userland/Libraries | |
parent | e64d0d43d23f36acb8030814303f5f936dd83894 (diff) | |
download | serenity-949d27f21bf8de89023427e3da342091041cb351.zip |
LibGL: Implement glDrawElements
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibGL/GL/gl.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLContext.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLVertexArrays.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 58 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.h | 4 |
5 files changed, 68 insertions, 1 deletions
diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 05f94e0c08..721b0f5152 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -362,6 +362,7 @@ GLAPI void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void* GLAPI void glColorPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); GLAPI void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count); +GLAPI void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index c0309a11e9..cab0b8beb4 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -70,6 +70,7 @@ public: virtual void gl_color_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) = 0; virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) = 0; virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) = 0; + virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/GLVertexArrays.cpp b/Userland/Libraries/LibGL/GLVertexArrays.cpp index fedfdadf90..46a3a8d2a9 100644 --- a/Userland/Libraries/LibGL/GLVertexArrays.cpp +++ b/Userland/Libraries/LibGL/GLVertexArrays.cpp @@ -28,3 +28,8 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { g_gl_context->gl_draw_arrays(mode, first, count); } + +void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) +{ + g_gl_context->gl_draw_elements(mode, count, type, indices); +} diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 1ff7d8ba30..f23c3b941d 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -1542,6 +1542,64 @@ void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count) glEnd(); } +void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_draw_elements, mode, count, type, indices); + RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); + + // FIXME: Some modes are still missing (GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES,GL_QUAD_STRIP) + RETURN_WITH_ERROR_IF(!(mode == GL_TRIANGLE_STRIP + || mode == GL_TRIANGLE_FAN + || mode == GL_TRIANGLES + || mode == GL_QUADS + || mode == GL_POLYGON), + GL_INVALID_ENUM); + + RETURN_WITH_ERROR_IF(!(type == GL_UNSIGNED_BYTE + || type == GL_UNSIGNED_SHORT + || type == GL_UNSIGNED_INT), + GL_INVALID_ENUM); + + RETURN_WITH_ERROR_IF(count < 0, GL_INVALID_VALUE); + + // At least the vertex array needs to be enabled + if (!m_client_side_vertex_array_enabled) + return; + + glBegin(mode); + for (int index = 0; index < count; index++) { + int i = 0; + switch (type) { + case GL_UNSIGNED_BYTE: + i = reinterpret_cast<const GLubyte*>(indices)[index]; + break; + case GL_UNSIGNED_SHORT: + i = reinterpret_cast<const GLushort*>(indices)[index]; + break; + case GL_UNSIGNED_INT: + i = reinterpret_cast<const GLuint*>(indices)[index]; + break; + } + + if (m_client_side_texture_coord_array_enabled) { + float tex_coords[4] { 0, 0, 0, 0 }; + read_from_vertex_attribute_pointer(m_client_tex_coord_pointer, i, tex_coords, false); + glTexCoord4fv(tex_coords); + } + + 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); + glColor4fv(color); + } + + float vertex[4] { 0, 0, 0, 1 }; + read_from_vertex_attribute_pointer(m_client_vertex_pointer, i, vertex, false); + glVertex4fv(vertex); + } + glEnd(); +} + // General helper function to read arbitrary vertex attribute data into a float array void SoftwareGLContext::read_from_vertex_attribute_pointer(VertexAttribPointer const& attrib, int index, float* elements, bool normalize) { diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 7c1243eec0..df7a062ab0 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -80,6 +80,7 @@ public: virtual void gl_color_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) override; virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) override; virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) override; + virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) override; virtual void present() override; @@ -210,7 +211,8 @@ private: decltype(&SoftwareGLContext::gl_read_buffer), decltype(&SoftwareGLContext::gl_tex_parameter), decltype(&SoftwareGLContext::gl_depth_mask), - decltype(&SoftwareGLContext::gl_draw_arrays)>; + decltype(&SoftwareGLContext::gl_draw_arrays), + decltype(&SoftwareGLContext::gl_draw_elements)>; using ExtraSavedArguments = Variant< FloatMatrix4x4>; |