LibGL: Implement glDrawArrays
This commit is contained in:
parent
b9261ade52
commit
e64d0d43d2
Notes:
sideshowbarker
2024-07-18 06:57:42 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/e64d0d43d23 Pull-request: https://github.com/SerenityOS/serenity/pull/9382 Reviewed-by: https://github.com/alimpfard
5 changed files with 147 additions and 1 deletions
|
@ -361,6 +361,7 @@ GLAPI void glDisableClientState(GLenum cap);
|
|||
GLAPI void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void* pointer);
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
virtual void gl_vertex_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) = 0;
|
||||
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 present() = 0;
|
||||
};
|
||||
|
|
|
@ -23,3 +23,8 @@ void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* poin
|
|||
{
|
||||
g_gl_context->gl_tex_coord_pointer(size, type, stride, pointer);
|
||||
}
|
||||
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
g_gl_context->gl_draw_arrays(mode, first, count);
|
||||
}
|
||||
|
|
|
@ -1501,6 +1501,141 @@ void SoftwareGLContext::gl_tex_coord_pointer(GLint size, GLenum type, GLsizei st
|
|||
m_client_tex_coord_pointer.pointer = pointer;
|
||||
}
|
||||
|
||||
void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count)
|
||||
{
|
||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_draw_arrays, mode, first, count);
|
||||
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(count < 0, GL_INVALID_VALUE);
|
||||
|
||||
// At least the vertex array needs to be enabled
|
||||
if (!m_client_side_vertex_array_enabled)
|
||||
return;
|
||||
|
||||
auto last = first + count;
|
||||
glBegin(mode);
|
||||
for (int i = first; i < last; i++) {
|
||||
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)
|
||||
{
|
||||
auto byte_ptr = reinterpret_cast<const char*>(attrib.pointer);
|
||||
size_t stride = attrib.stride;
|
||||
|
||||
switch (attrib.type) {
|
||||
case GL_BYTE: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLbyte) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLbyte*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0x80;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_BYTE: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLubyte) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLubyte*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_SHORT: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLshort) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLshort*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0x8000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_SHORT: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLushort) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLushort*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0xffff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_INT: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLint) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLint*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0x80000000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_UNSIGNED_INT: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLuint) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLuint*>(byte_ptr + stride * index) + i);
|
||||
if (normalize)
|
||||
elements[i] /= 0xffffffff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_FLOAT: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLfloat) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = *(reinterpret_cast<const GLfloat*>(byte_ptr + stride * index) + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_DOUBLE: {
|
||||
if (stride == 0)
|
||||
stride = sizeof(GLdouble) * attrib.size;
|
||||
|
||||
for (int i = 0; i < attrib.size; i++) {
|
||||
elements[i] = static_cast<float>(*(reinterpret_cast<const GLdouble*>(byte_ptr + stride * index) + i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoftwareGLContext::present()
|
||||
{
|
||||
m_rasterizer.blit_to(*m_frontbuffer);
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
virtual void gl_vertex_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) override;
|
||||
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 present() override;
|
||||
|
||||
|
@ -208,7 +209,8 @@ private:
|
|||
decltype(&SoftwareGLContext::gl_hint),
|
||||
decltype(&SoftwareGLContext::gl_read_buffer),
|
||||
decltype(&SoftwareGLContext::gl_tex_parameter),
|
||||
decltype(&SoftwareGLContext::gl_depth_mask)>;
|
||||
decltype(&SoftwareGLContext::gl_depth_mask),
|
||||
decltype(&SoftwareGLContext::gl_draw_arrays)>;
|
||||
|
||||
using ExtraSavedArguments = Variant<
|
||||
FloatMatrix4x4>;
|
||||
|
@ -234,6 +236,8 @@ private:
|
|||
const void* pointer { 0 };
|
||||
};
|
||||
|
||||
static void read_from_vertex_attribute_pointer(VertexAttribPointer const&, int index, float* elements, bool normalize);
|
||||
|
||||
VertexAttribPointer m_client_vertex_pointer;
|
||||
VertexAttribPointer m_client_color_pointer;
|
||||
VertexAttribPointer m_client_tex_coord_pointer;
|
||||
|
|
Loading…
Add table
Reference in a new issue