diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2021-08-21 14:49:27 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-26 19:53:57 +0200 |
commit | 19a08ff1876e260ab2526db36d3ad47d59cf5c4c (patch) | |
tree | 0077dcdae49a0d1aa23f3cf63a3c2ad851a5a863 | |
parent | eb368a5000512200bae2a51ef97c6ed1beda7c47 (diff) | |
download | serenity-19a08ff1876e260ab2526db36d3ad47d59cf5c4c.zip |
LibGL: Implement glPixelStorei
This sets the length of a row for the image to be transferred. This
value is measured in pixels. When a rectangle with a width less than
this value is transferred the remaining pixels of this row are skipped.
-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/GLUtils.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/Texture2D.cpp | 90 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/Texture2D.h | 2 |
7 files changed, 83 insertions, 35 deletions
diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index ac97e8b381..bc9654e54b 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -377,6 +377,7 @@ GLAPI void glPolygonMode(GLenum face, GLenum mode); GLAPI void glFogfv(GLenum mode, GLfloat* params); GLAPI void glFogf(GLenum pname, GLfloat param); GLAPI void glFogi(GLenum pname, GLint param); +GLAPI void glPixelStorei(GLenum pname, GLint param); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 51793a9975..b1e869fab0 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -80,6 +80,7 @@ public: virtual void gl_fogfv(GLenum pname, GLfloat* params) = 0; virtual void gl_fogf(GLenum pname, GLfloat params) = 0; virtual void gl_fogi(GLenum pname, GLint param) = 0; + virtual void gl_pixel_store(GLenum pname, GLfloat param) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp index e03fcd70f5..0722dfa072 100644 --- a/Userland/Libraries/LibGL/GLUtils.cpp +++ b/Userland/Libraries/LibGL/GLUtils.cpp @@ -134,3 +134,8 @@ void glPolygonMode(GLenum face, GLenum mode) { g_gl_context->gl_polygon_mode(face, mode); } + +void glPixelStorei(GLenum pname, GLint param) +{ + g_gl_context->gl_pixel_store(pname, param); +} diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 009b8e7512..0cc5f507a0 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -650,7 +650,7 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern RETURN_WITH_ERROR_IF((width & 2) != 0 || (height & 2) != 0, GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(border < 0 || border > 1, GL_INVALID_VALUE); - m_active_texture_unit->bound_texture_2d()->upload_texture_data(target, level, internal_format, width, height, border, format, type, data); + m_active_texture_unit->bound_texture_2d()->upload_texture_data(target, level, internal_format, width, height, border, format, type, data, m_unpack_row_length); } void SoftwareGLContext::gl_tex_parameter(GLenum target, GLenum pname, GLfloat param) @@ -1805,6 +1805,20 @@ void SoftwareGLContext::gl_fogi(GLenum pname, GLint param) m_rasterizer.set_options(options); } +void SoftwareGLContext::gl_pixel_store(GLenum pname, GLfloat param) +{ + // FIXME: Implement missing parameters + switch (pname) { + case GL_UNPACK_ROW_LENGTH: + RETURN_WITH_ERROR_IF(param < 0, GL_INVALID_VALUE); + m_unpack_row_length = static_cast<size_t>(param); + break; + default: + RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); + break; + } +} + void SoftwareGLContext::present() { m_rasterizer.blit_to(*m_frontbuffer); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 3239c13afb..23ad3e2db9 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -90,6 +90,7 @@ public: virtual void gl_fogfv(GLenum pname, GLfloat* params) override; virtual void gl_fogf(GLenum pname, GLfloat param) override; virtual void gl_fogi(GLenum pname, GLint param) override; + virtual void gl_pixel_store(GLenum pname, GLfloat param) override; virtual void present() override; private: @@ -254,6 +255,8 @@ private: VertexAttribPointer m_client_vertex_pointer; VertexAttribPointer m_client_color_pointer; VertexAttribPointer m_client_tex_coord_pointer; + + size_t m_unpack_row_length { 0 }; }; } diff --git a/Userland/Libraries/LibGL/Tex/Texture2D.cpp b/Userland/Libraries/LibGL/Tex/Texture2D.cpp index b0fd569c13..f401f61186 100644 --- a/Userland/Libraries/LibGL/Tex/Texture2D.cpp +++ b/Userland/Libraries/LibGL/Tex/Texture2D.cpp @@ -12,7 +12,7 @@ namespace GL { -void Texture2D::upload_texture_data(GLenum, GLint lod, GLint internal_format, GLsizei width, GLsizei height, GLint, GLenum format, GLenum, const GLvoid* pixels) +void Texture2D::upload_texture_data(GLenum, GLint lod, GLint internal_format, GLsizei width, GLsizei height, GLint, GLenum format, GLenum, const GLvoid* pixels, size_t pixels_per_row) { // NOTE: Some target, format, and internal formats are currently unsupported. // Considering we control this library, and `gl.h` itself, we don't need to add any @@ -34,44 +34,68 @@ void Texture2D::upload_texture_data(GLenum, GLint lod, GLint internal_format, GL mip.pixel_data().clear(); if (format == GL_RGBA) { - for (auto i = 0; i < width * height * 4; i += 4) { - u32 r = pixel_byte_array[i + 0]; - u32 g = pixel_byte_array[i + 1]; - u32 b = pixel_byte_array[i + 2]; - u32 a = pixel_byte_array[i + 3]; - - u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); - mip.pixel_data().append(pixel); + for (auto y = 0; y < height; y++) { + for (auto x = 0; x < width; x++) { + u32 r = *pixel_byte_array++; + u32 g = *pixel_byte_array++; + u32 b = *pixel_byte_array++; + u32 a = *pixel_byte_array++; + + u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); + mip.pixel_data().append(pixel); + } + + if (pixels_per_row > 0) { + pixel_byte_array += (pixels_per_row - width) * 4; + } } } else if (format == GL_BGRA) { - for (auto i = 0; i < width * height * 4; i += 4) { - u32 b = pixel_byte_array[i + 0]; - u32 g = pixel_byte_array[i + 1]; - u32 r = pixel_byte_array[i + 2]; - u32 a = pixel_byte_array[i + 3]; - - u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); - mip.pixel_data().append(pixel); + for (auto y = 0; y < height; y++) { + for (auto x = 0; x < width; x++) { + u32 b = *pixel_byte_array++; + u32 g = *pixel_byte_array++; + u32 r = *pixel_byte_array++; + u32 a = *pixel_byte_array++; + + u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); + mip.pixel_data().append(pixel); + } + + if (pixels_per_row > 0) { + pixel_byte_array += (pixels_per_row - width) * 4; + } } } else if (format == GL_BGR) { - for (auto i = 0; i < width * height * 3; i += 3) { - u32 b = pixel_byte_array[i + 0]; - u32 g = pixel_byte_array[i + 1]; - u32 r = pixel_byte_array[i + 2]; - u32 a = 255; - - u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); - mip.pixel_data().append(pixel); + for (auto y = 0; y < height; y++) { + for (auto x = 0; x < width; x++) { + u32 b = *pixel_byte_array++; + u32 g = *pixel_byte_array++; + u32 r = *pixel_byte_array++; + u32 a = 255; + + u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); + mip.pixel_data().append(pixel); + } + + if (pixels_per_row > 0) { + pixel_byte_array += (pixels_per_row - width) * 3; + } } } else if (format == GL_RGB) { - for (auto i = 0; i < width * height * 3; i += 3) { - u32 r = pixel_byte_array[i + 0]; - u32 g = pixel_byte_array[i + 1]; - u32 b = pixel_byte_array[i + 2]; - u32 a = 255; - - u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); - mip.pixel_data().append(pixel); + for (auto y = 0; y < height; y++) { + for (auto x = 0; x < width; x++) { + u32 r = *pixel_byte_array++; + u32 g = *pixel_byte_array++; + u32 b = *pixel_byte_array++; + u32 a = 255; + + u32 pixel = ((a << 24) | (r << 16) | (g << 8) | b); + mip.pixel_data().append(pixel); + } + + if (pixels_per_row > 0) { + pixel_byte_array += (pixels_per_row - width) * 3; + } } } else { VERIFY_NOT_REACHED(); diff --git a/Userland/Libraries/LibGL/Tex/Texture2D.h b/Userland/Libraries/LibGL/Tex/Texture2D.h index a281f06be1..b94acade8c 100644 --- a/Userland/Libraries/LibGL/Tex/Texture2D.h +++ b/Userland/Libraries/LibGL/Tex/Texture2D.h @@ -35,7 +35,7 @@ public: virtual bool is_texture_2d() const override { return true; } - void upload_texture_data(GLenum target, GLint lod, GLint internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); + void upload_texture_data(GLenum target, GLint lod, GLint internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels, size_t pixels_per_row); void replace_sub_texture_data(GLint lod, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* data); MipMap const& mipmap(unsigned lod) const; |