summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGL
diff options
context:
space:
mode:
authorStephan Unverwerth <s.unverwerth@serenityos.org>2021-08-13 15:37:38 +0200
committerAndreas Kling <kling@serenityos.org>2021-08-14 12:49:29 +0200
commit949d27f21bf8de89023427e3da342091041cb351 (patch)
tree9da9e2e02909ff9e18dc5a5dce3f6d2181c9e5f7 /Userland/Libraries/LibGL
parente64d0d43d23f36acb8030814303f5f936dd83894 (diff)
downloadserenity-949d27f21bf8de89023427e3da342091041cb351.zip
LibGL: Implement glDrawElements
Diffstat (limited to 'Userland/Libraries/LibGL')
-rw-r--r--Userland/Libraries/LibGL/GL/gl.h1
-rw-r--r--Userland/Libraries/LibGL/GLContext.h1
-rw-r--r--Userland/Libraries/LibGL/GLVertexArrays.cpp5
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp58
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h4
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>;