mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:12:45 +00:00 
			
		
		
		
	LibGL: Implement glScissor()
				
					
				
			This commit is contained in:
		
							parent
							
								
									6dd2ebfe8e
								
							
						
					
					
						commit
						bb58f6ccab
					
				
					 9 changed files with 83 additions and 10 deletions
				
			
		|  | @ -183,11 +183,15 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re | |||
|     }; | ||||
| 
 | ||||
|     // Calculate block-based bounds
 | ||||
|     auto render_bounds = render_target.rect(); | ||||
|     if (options.scissor_enabled) | ||||
|         render_bounds.intersect(options.scissor_box); | ||||
|     int const block_padding = RASTERIZER_BLOCK_SIZE - 1; | ||||
|     // clang-format off
 | ||||
|     const int bx0 = max(0,                      min(min(v0.x(), v1.x()), v2.x())                            ) / RASTERIZER_BLOCK_SIZE; | ||||
|     const int bx1 = min(render_target.width(),  max(max(v0.x(), v1.x()), v2.x()) + RASTERIZER_BLOCK_SIZE - 1) / RASTERIZER_BLOCK_SIZE; | ||||
|     const int by0 = max(0,                      min(min(v0.y(), v1.y()), v2.y())                            ) / RASTERIZER_BLOCK_SIZE; | ||||
|     const int by1 = min(render_target.height(), max(max(v0.y(), v1.y()), v2.y()) + RASTERIZER_BLOCK_SIZE - 1) / RASTERIZER_BLOCK_SIZE; | ||||
|     int const bx0 =  max(render_bounds.left(),   min(min(v0.x(), v1.x()), v2.x()))                  / RASTERIZER_BLOCK_SIZE; | ||||
|     int const bx1 = (min(render_bounds.right(),  max(max(v0.x(), v1.x()), v2.x())) + block_padding) / RASTERIZER_BLOCK_SIZE; | ||||
|     int const by0 =  max(render_bounds.top(),    min(min(v0.y(), v1.y()), v2.y()))                  / RASTERIZER_BLOCK_SIZE; | ||||
|     int const by1 = (min(render_bounds.bottom(), max(max(v0.y(), v1.y()), v2.y())) + block_padding) / RASTERIZER_BLOCK_SIZE; | ||||
|     // clang-format on
 | ||||
| 
 | ||||
|     static_assert(RASTERIZER_BLOCK_SIZE < sizeof(int) * 8, "RASTERIZER_BLOCK_SIZE must be smaller than the pixel_mask's width in bits"); | ||||
|  | @ -229,11 +233,10 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re | |||
|             int y0 = by * RASTERIZER_BLOCK_SIZE; | ||||
| 
 | ||||
|             // Generate the coverage mask
 | ||||
|             if (test_point(b0) && test_point(b1) && test_point(b2) && test_point(b3)) { | ||||
|             if (!options.scissor_enabled && test_point(b0) && test_point(b1) && test_point(b2) && test_point(b3)) { | ||||
|                 // The block is fully contained within the triangle. Fill the mask with all 1s
 | ||||
|                 for (int y = 0; y < RASTERIZER_BLOCK_SIZE; y++) { | ||||
|                 for (int y = 0; y < RASTERIZER_BLOCK_SIZE; y++) | ||||
|                     pixel_mask[y] = -1; | ||||
|                 } | ||||
|             } else { | ||||
|                 // The block overlaps at least one triangle edge.
 | ||||
|                 // We need to test coverage of every pixel within the block.
 | ||||
|  | @ -242,7 +245,7 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re | |||
|                     pixel_mask[y] = 0; | ||||
| 
 | ||||
|                     for (int x = 0; x < RASTERIZER_BLOCK_SIZE; x++, coords += dbdx) { | ||||
|                         if (test_point(coords)) | ||||
|                         if (test_point(coords) && (!options.scissor_enabled || render_bounds.contains(x0 + x, y0 + y))) | ||||
|                             pixel_mask[y] |= 1 << x; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -481,6 +484,7 @@ SoftwareRasterizer::SoftwareRasterizer(const Gfx::IntSize& min_size) | |||
|     : m_render_target { Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, closest_multiple(min_size, RASTERIZER_BLOCK_SIZE)).release_value_but_fixme_should_propagate_errors() } | ||||
|     , m_depth_buffer { adopt_own(*new DepthBuffer(closest_multiple(min_size, RASTERIZER_BLOCK_SIZE))) } | ||||
| { | ||||
|     m_options.scissor_box = m_render_target->rect(); | ||||
| } | ||||
| 
 | ||||
| void SoftwareRasterizer::submit_triangle(const GLTriangle& triangle, const Array<TextureUnit, 32>& texture_units) | ||||
|  | @ -559,14 +563,28 @@ void SoftwareRasterizer::clear_color(const FloatVector4& color) | |||
|     uint8_t g = static_cast<uint8_t>(clamp(color.y(), 0.0f, 1.0f) * 255); | ||||
|     uint8_t b = static_cast<uint8_t>(clamp(color.z(), 0.0f, 1.0f) * 255); | ||||
|     uint8_t a = static_cast<uint8_t>(clamp(color.w(), 0.0f, 1.0f) * 255); | ||||
|     auto const fill_color = Gfx::Color(r, g, b, a); | ||||
| 
 | ||||
|     m_render_target->fill(Gfx::Color(r, g, b, a)); | ||||
|     if (m_options.scissor_enabled) { | ||||
|         auto fill_rect = m_render_target->rect(); | ||||
|         fill_rect.intersect(m_options.scissor_box); | ||||
|         Gfx::Painter painter { *m_render_target }; | ||||
|         painter.fill_rect(fill_rect, fill_color); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     m_render_target->fill(fill_color); | ||||
| } | ||||
| 
 | ||||
| void SoftwareRasterizer::clear_depth(float depth) | ||||
| { | ||||
|     wait_for_all_threads(); | ||||
| 
 | ||||
|     if (m_options.scissor_enabled) { | ||||
|         m_depth_buffer->clear(m_options.scissor_box, depth); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     m_depth_buffer->clear(depth); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jelle Raaijmakers
						Jelle Raaijmakers