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.
This commit is contained in:
parent
eb368a5000
commit
19a08ff187
Notes:
sideshowbarker
2024-07-18 05:16:25 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/19a08ff1876 Pull-request: https://github.com/SerenityOS/serenity/pull/9550 Reviewed-by: https://github.com/Quaker762 ✅
7 changed files with 79 additions and 31 deletions
Userland/Libraries/LibGL
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
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);
|
||||
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];
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue