diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index f27bcde2dce..208f4896148 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -2243,26 +2243,42 @@ void SoftwareGLContext::gl_draw_pixels(GLsizei width, GLsizei height, GLenum for RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - // FIXME: we only support RGBA + GL_UNSIGNED_BYTE, implement all the others! - if (format != GL_RGBA) { - dbgln_if(GL_DEBUG, "gl_draw_pixels(): support for format {:#x} not implemented", format); - return; - } else if (type != GL_UNSIGNED_BYTE) { - dbgln_if(GL_DEBUG, "gl_draw_pixels(): support for type {:#x} not implemented", type); + // FIXME: we only support RGBA + UNSIGNED_BYTE and DEPTH_COMPONENT + UNSIGNED_SHORT, implement all combinations! + if (!((format == GL_RGBA && type == GL_UNSIGNED_BYTE) || (format == GL_DEPTH_COMPONENT && type == GL_UNSIGNED_SHORT))) { + dbgln_if(GL_DEBUG, "gl_draw_pixels(): support for format {:#x} and/or type {:#x} not implemented", format, type); return; } - auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, { width, height }); - RETURN_WITH_ERROR_IF(bitmap_or_error.is_error(), GL_OUT_OF_MEMORY); - auto bitmap = bitmap_or_error.release_value(); + // FIXME: implement support for pixel parameters such as GL_UNPACK_ALIGNMENT - // FIXME: implement support for GL_UNPACK_ALIGNMENT and other pixel parameters - auto pixel_data = static_cast(data); - for (int y = 0; y < height; ++y) - for (int x = 0; x < width; ++x) - bitmap->set_pixel(x, y, Color::from_rgba(*(pixel_data++))); + if (format == GL_RGBA) { + auto bitmap_or_error = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, { width, height }); + RETURN_WITH_ERROR_IF(bitmap_or_error.is_error(), GL_OUT_OF_MEMORY); + auto bitmap = bitmap_or_error.release_value(); - m_rasterizer.blit_to_color_buffer_at_raster_position(bitmap); + auto pixel_data = static_cast(data); + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + bitmap->set_pixel(x, y, Color::from_rgba(*(pixel_data++))); + + m_rasterizer.blit_to_color_buffer_at_raster_position(bitmap); + } else if (format == GL_DEPTH_COMPONENT) { + Vector depth_values; + depth_values.ensure_capacity(width * height); + + auto depth_data = static_cast(data); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + auto u16_value = *(depth_data++); + auto float_value = static_cast(u16_value) / NumericLimits::max(); + depth_values.append(float_value); + } + } + + m_rasterizer.blit_to_depth_buffer_at_raster_position(depth_values, width, height); + } else { + VERIFY_NOT_REACHED(); + } } void SoftwareGLContext::gl_depth_range(GLdouble min, GLdouble max) diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index 096b24f5add..f512363ef80 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -992,6 +992,26 @@ void Device::blit_to_color_buffer_at_raster_position(Gfx::Bitmap const& source) painter.blit({ blit_rect.x(), blit_rect.y() }, source, source.rect(), 1.0f, true); } +void Device::blit_to_depth_buffer_at_raster_position(Vector const& depth_values, size_t width, size_t height) +{ + if (!m_raster_position.valid) + return; + + auto const raster_rect = raster_rect_in_target_coordinates({ width, height }); + auto const y1 = raster_rect.y(); + auto const y2 = y1 + height; + auto const x1 = raster_rect.x(); + int const x2 = x1 + width; + + auto index = 0; + for (int y = y2 - 1; y >= y1; --y) { + auto depth_line = m_depth_buffer->scanline(y); + for (int x = x1; x < x2; ++x) { + depth_line[x] = depth_values.at(index++); + } + } +} + void Device::blit_to(Gfx::Bitmap& target) { wait_for_all_threads(); diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index 538181fe790..362ea7c1f56 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -105,6 +105,7 @@ public: void clear_depth(float); void blit_to(Gfx::Bitmap&); void blit_to_color_buffer_at_raster_position(Gfx::Bitmap const&); + void blit_to_depth_buffer_at_raster_position(Vector const&, size_t, size_t); void wait_for_all_threads() const; void set_options(const RasterizerOptions&); void set_light_model_params(const LightModelParameters&);