diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index b43e47f200..f27bcde2dc 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -2262,10 +2262,7 @@ void SoftwareGLContext::gl_draw_pixels(GLsizei width, GLsizei height, GLenum for for (int x = 0; x < width; ++x) bitmap->set_pixel(x, y, Color::from_rgba(*(pixel_data++))); - m_rasterizer.blit( - bitmap, - static_cast(m_current_raster_position.window_coordinates.x()), - static_cast(m_current_raster_position.window_coordinates.y())); + m_rasterizer.blit_to_color_buffer_at_raster_position(bitmap); } void SoftwareGLContext::gl_depth_range(GLdouble min, GLdouble max) @@ -2686,8 +2683,7 @@ void SoftwareGLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_raster_pos, x, y, z, w); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - m_current_raster_position.window_coordinates = { x, y, z }; - m_current_raster_position.clip_coordinate_value = w; + m_rasterizer.set_raster_position({ x, y, z, w }, m_model_view_matrix, m_projection_matrix); } void SoftwareGLContext::gl_line_width(GLfloat width) @@ -2751,8 +2747,14 @@ void SoftwareGLContext::gl_bitmap(GLsizei width, GLsizei height, GLfloat xorig, APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_bitmap, width, height, xorig, yorig, xmove, ymove, bitmap); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - // FIXME: implement - dbgln_if(GL_DEBUG, "SoftwareGLContext FIXME: implement gl_bitmap({}, {}, {}, {}, {}, {}, {})", width, height, xorig, yorig, xmove, ymove, bitmap); + if (bitmap != nullptr) { + // FIXME: implement + dbgln_if(GL_DEBUG, "gl_bitmap({}, {}, {}, {}, {}, {}, {}): unimplemented", width, height, xorig, yorig, xmove, ymove, bitmap); + } + + auto raster_position = m_rasterizer.raster_position(); + raster_position.window_coordinates += { xmove, ymove, 0.f, 0.f }; + m_rasterizer.set_raster_position(raster_position); } void SoftwareGLContext::gl_copy_tex_image_2d(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 70ad47254d..05211c9b3b 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -418,17 +418,6 @@ private: GLsizei m_unpack_row_length { 0 }; u8 m_unpack_alignment { 4 }; - struct RasterPosition { - FloatVector3 window_coordinates { 0.0f, 0.0f, 0.0f }; - float clip_coordinate_value { 1.0f }; - float eye_coordinate_distance { 0.0f }; - bool valid { true }; - FloatVector4 color_rgba { 1.0f, 1.0f, 1.0f, 1.0f }; - float color_index { 1.0f }; - FloatVector4 texture_coordinates { 0.0f, 0.0f, 0.0f, 1.0f }; - }; - RasterPosition m_current_raster_position; - float m_line_width { 1.0f }; // Lighting configuration diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index 56988ff0a0..096b24f5ad 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -82,7 +82,7 @@ static Vector4 to_vec4(u32x4 rgba) }; } -static Gfx::IntRect window_coordinates_to_target_coordinates(Gfx::IntRect const& window_rect, Gfx::IntRect const& target_rect) +static Gfx::IntRect window_coordinates_to_target_coordinates(Gfx::IntRect const window_rect, Gfx::IntRect const target_rect) { return { window_rect.x(), @@ -977,15 +977,19 @@ void Device::clear_depth(float depth) m_depth_buffer->clear(depth); } -void Device::blit(Gfx::Bitmap const& source, int x, int y) +void Device::blit_to_color_buffer_at_raster_position(Gfx::Bitmap const& source) { + if (!m_raster_position.valid) + return; + wait_for_all_threads(); INCREASE_STATISTICS_COUNTER(g_num_pixels, source.width() * source.height()); INCREASE_STATISTICS_COUNTER(g_num_pixels_shaded, source.width() * source.height()); Gfx::Painter painter { *m_render_target }; - painter.blit({ x, y }, source, source.rect(), 1.0f, true); + auto const blit_rect = raster_rect_in_target_coordinates(source.size()); + painter.blit({ blit_rect.x(), blit_rect.y() }, source, source.rect(), 1.0f, true); } void Device::blit_to(Gfx::Bitmap& target) @@ -1124,4 +1128,51 @@ void Device::set_material_state(unsigned int material_id, Material const& materi m_materials.at(material_id) = material; } +void Device::set_raster_position(RasterPosition const& raster_position) +{ + m_raster_position = raster_position; +} + +void Device::set_raster_position(FloatVector4 const& position, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform) +{ + auto const eye_coordinates = model_view_transform * position; + auto const clip_coordinates = projection_transform * eye_coordinates; + + // FIXME: implement clipping + m_raster_position.valid = true; + + auto ndc_coordinates = clip_coordinates / clip_coordinates.w(); + ndc_coordinates.set_w(clip_coordinates.w()); + + auto const viewport = m_options.viewport; + auto const viewport_half_width = viewport.width() / 2.0f; + auto const viewport_half_height = viewport.height() / 2.0f; + auto const viewport_center_x = viewport.x() + viewport_half_width; + auto const viewport_center_y = viewport.y() + viewport_half_height; + auto const depth_half_range = (m_options.depth_max - m_options.depth_min) / 2; + auto const depth_halfway = (m_options.depth_min + m_options.depth_max) / 2; + + // FIXME: implement other raster position properties such as color and texcoords + + m_raster_position.window_coordinates = { + viewport_center_x + ndc_coordinates.x() * viewport_half_width, + viewport_center_y + ndc_coordinates.y() * viewport_half_height, + depth_halfway + ndc_coordinates.z() * depth_half_range, + ndc_coordinates.w(), + }; + + m_raster_position.eye_coordinate_distance = eye_coordinates.length(); +} + +Gfx::IntRect Device::raster_rect_in_target_coordinates(Gfx::IntSize size) +{ + auto const raster_rect = Gfx::IntRect { + static_cast(m_raster_position.window_coordinates.x()), + static_cast(m_raster_position.window_coordinates.y()), + size.width(), + size.height(), + }; + return window_coordinates_to_target_coordinates(raster_rect, m_render_target->rect()); +} + } diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index a0bdc80ae3..538181fe79 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -84,6 +84,15 @@ struct LightModelParameters { struct PixelQuad; +struct RasterPosition { + FloatVector4 window_coordinates { 0.0f, 0.0f, 0.0f, 1.0f }; + float eye_coordinate_distance { 0.0f }; + bool valid { true }; + FloatVector4 color_rgba { 1.0f, 1.0f, 1.0f, 1.0f }; + float color_index { 1.0f }; + FloatVector4 texture_coordinates { 0.0f, 0.0f, 0.0f, 1.0f }; +}; + class Device final { public: Device(const Gfx::IntSize& min_size); @@ -94,8 +103,8 @@ public: void resize(const Gfx::IntSize& min_size); void clear_color(const FloatVector4&); void clear_depth(float); - void blit(Gfx::Bitmap const&, int x, int y); void blit_to(Gfx::Bitmap&); + void blit_to_color_buffer_at_raster_position(Gfx::Bitmap const&); void wait_for_all_threads() const; void set_options(const RasterizerOptions&); void set_light_model_params(const LightModelParameters&); @@ -110,8 +119,13 @@ public: void set_light_state(unsigned, Light const&); void set_material_state(unsigned, Material const&); + RasterPosition raster_position() const { return m_raster_position; } + void set_raster_position(RasterPosition const& raster_position); + void set_raster_position(FloatVector4 const& position, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform); + private: void draw_statistics_overlay(Gfx::Bitmap&); + Gfx::IntRect raster_rect_in_target_coordinates(Gfx::IntSize size); void rasterize_triangle(const Triangle& triangle); void setup_blend_factors(); @@ -132,6 +146,7 @@ private: AlphaBlendFactors m_alpha_blend_factors; Array m_lights; Array m_materials; + RasterPosition m_raster_position; }; }