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:
Stephan Unverwerth 2021-08-21 14:49:27 +02:00 committed by Andreas Kling
parent eb368a5000
commit 19a08ff187
Notes: sideshowbarker 2024-07-18 05:16:25 +09:00
7 changed files with 79 additions and 31 deletions

View file

@ -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
}

View file

@ -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;
};

View file

@ -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);
}

View file

@ -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);

View file

@ -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 };
};
}

View file

@ -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();

View file

@ -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;