summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Unverwerth <s.unverwerth@serenityos.org>2021-08-21 14:49:27 +0200
committerAndreas Kling <kling@serenityos.org>2021-08-26 19:53:57 +0200
commit19a08ff1876e260ab2526db36d3ad47d59cf5c4c (patch)
tree0077dcdae49a0d1aa23f3cf63a3c2ad851a5a863
parenteb368a5000512200bae2a51ef97c6ed1beda7c47 (diff)
downloadserenity-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.h1
-rw-r--r--Userland/Libraries/LibGL/GLContext.h1
-rw-r--r--Userland/Libraries/LibGL/GLUtils.cpp5
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp16
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h3
-rw-r--r--Userland/Libraries/LibGL/Tex/Texture2D.cpp90
-rw-r--r--Userland/Libraries/LibGL/Tex/Texture2D.h2
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;