mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +00:00 
			
		
		
		
	LibGL: Implement glDrawPixels and add stub for glBitmap
				
					
				
			This commit is contained in:
		
							parent
							
								
									c2960e68a8
								
							
						
					
					
						commit
						401472c9a4
					
				
					 7 changed files with 149 additions and 1 deletions
				
			
		|  | @ -201,6 +201,18 @@ extern "C" { | |||
| 
 | ||||
| // Source pixel data format
 | ||||
| #define GL_UNSIGNED_BYTE 0x1401 | ||||
| #define GL_UNSIGNED_BYTE_3_3_2 0x8032 | ||||
| #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 | ||||
| #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 | ||||
| #define GL_UNSIGNED_INT_8_8_8_8 0x8035 | ||||
| #define GL_UNSIGNED_INT_10_10_10_2 0x8036 | ||||
| #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 | ||||
| #define GL_UNSIGNED_SHORT_5_6_5 0x8363 | ||||
| #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 | ||||
| #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 | ||||
| #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 | ||||
| #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 | ||||
| #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 | ||||
| 
 | ||||
| // Stencil buffer operations
 | ||||
| #define GL_KEEP 0x1E00 | ||||
|  | @ -450,6 +462,7 @@ GLAPI void glColorPointer(GLint size, GLenum type, GLsizei stride, const void* p | |||
| GLAPI void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); | ||||
| GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count); | ||||
| GLAPI void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); | ||||
| GLAPI void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data); | ||||
| GLAPI void glDepthRange(GLdouble nearVal, GLdouble farVal); | ||||
| GLAPI void glDepthFunc(GLenum func); | ||||
| GLAPI void glPolygonMode(GLenum face, GLenum mode); | ||||
|  | @ -475,6 +488,7 @@ GLAPI void glMaterialfv(GLenum face, GLenum pname, GLfloat const* params); | |||
| GLAPI void glLineWidth(GLfloat width); | ||||
| GLAPI void glPushAttrib(GLbitfield mask); | ||||
| GLAPI void glPopAttrib(); | ||||
| GLAPI void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  |  | |||
|  | @ -79,6 +79,7 @@ public: | |||
|     virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) = 0; | ||||
|     virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) = 0; | ||||
|     virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) = 0; | ||||
|     virtual void gl_draw_pixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) = 0; | ||||
|     virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = 0; | ||||
|     virtual void gl_get_booleanv(GLenum pname, GLboolean* data) = 0; | ||||
|     virtual void gl_get_doublev(GLenum pname, GLdouble* params) = 0; | ||||
|  | @ -102,6 +103,7 @@ public: | |||
|     virtual void gl_push_attrib(GLbitfield mask) = 0; | ||||
|     virtual void gl_pop_attrib() = 0; | ||||
|     virtual void gl_light_model(GLenum pname, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0; | ||||
|     virtual void gl_bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap) = 0; | ||||
| 
 | ||||
|     virtual void present() = 0; | ||||
| }; | ||||
|  |  | |||
|  | @ -9,6 +9,16 @@ | |||
| 
 | ||||
| extern GL::GLContext* g_gl_context; | ||||
| 
 | ||||
| void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap) | ||||
| { | ||||
|     g_gl_context->gl_bitmap(width, height, xorig, yorig, xmove, ymove, bitmap); | ||||
| } | ||||
| 
 | ||||
| void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) | ||||
| { | ||||
|     g_gl_context->gl_draw_pixels(width, height, format, type, data); | ||||
| } | ||||
| 
 | ||||
| void glLineWidth(GLfloat width) | ||||
| { | ||||
|     g_gl_context->gl_line_width(width); | ||||
|  |  | |||
|  | @ -1926,6 +1926,106 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type | |||
|     glEnd(); | ||||
| } | ||||
| 
 | ||||
| void SoftwareGLContext::gl_draw_pixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) | ||||
| { | ||||
|     APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_draw_pixels, width, height, format, type, data); | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(!(format == GL_COLOR_INDEX | ||||
|                              || format == GL_STENCIL_INDEX | ||||
|                              || format == GL_DEPTH_COMPONENT | ||||
|                              || format == GL_RGBA | ||||
|                              || format == GL_BGRA | ||||
|                              || format == GL_RED | ||||
|                              || format == GL_GREEN | ||||
|                              || format == GL_BLUE | ||||
|                              || format == GL_ALPHA | ||||
|                              || format == GL_RGB | ||||
|                              || format == GL_BGR | ||||
|                              || format == GL_LUMINANCE | ||||
|                              || format == GL_LUMINANCE_ALPHA), | ||||
|         GL_INVALID_ENUM); | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(!(type == GL_UNSIGNED_BYTE | ||||
|                              || type == GL_BYTE | ||||
|                              || type == GL_BITMAP | ||||
|                              || type == GL_UNSIGNED_SHORT | ||||
|                              || type == GL_SHORT | ||||
|                              || type == GL_UNSIGNED_INT | ||||
|                              || type == GL_INT | ||||
|                              || type == GL_FLOAT | ||||
|                              || type == GL_UNSIGNED_BYTE_3_3_2 | ||||
|                              || type == GL_UNSIGNED_BYTE_2_3_3_REV | ||||
|                              || type == GL_UNSIGNED_SHORT_5_6_5 | ||||
|                              || type == GL_UNSIGNED_SHORT_5_6_5_REV | ||||
|                              || type == GL_UNSIGNED_SHORT_4_4_4_4 | ||||
|                              || type == GL_UNSIGNED_SHORT_4_4_4_4_REV | ||||
|                              || type == GL_UNSIGNED_SHORT_5_5_5_1 | ||||
|                              || type == GL_UNSIGNED_SHORT_1_5_5_5_REV | ||||
|                              || type == GL_UNSIGNED_INT_8_8_8_8 | ||||
|                              || type == GL_UNSIGNED_INT_8_8_8_8_REV | ||||
|                              || type == GL_UNSIGNED_INT_10_10_10_2 | ||||
|                              || type == GL_UNSIGNED_INT_2_10_10_10_REV), | ||||
|         GL_INVALID_ENUM); | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(type == GL_BITMAP && !(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX), GL_INVALID_ENUM); | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE); | ||||
| 
 | ||||
|     // FIXME: GL_INVALID_OPERATION is generated if format is GL_STENCIL_INDEX and there is no stencil buffer
 | ||||
|     // FIXME: GL_INVALID_OPERATION is generated if format is GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA,
 | ||||
|     //        GL_BGR, GL_BGRA, GL_LUMINANCE, or GL_LUMINANCE_ALPHA, and the GL is in color index mode
 | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(format != GL_RGB | ||||
|             && (type == GL_UNSIGNED_BYTE_3_3_2 | ||||
|                 || type == GL_UNSIGNED_BYTE_2_3_3_REV | ||||
|                 || type == GL_UNSIGNED_SHORT_5_6_5 | ||||
|                 || type == GL_UNSIGNED_SHORT_5_6_5_REV), | ||||
|         GL_INVALID_OPERATION); | ||||
| 
 | ||||
|     RETURN_WITH_ERROR_IF(!(format == GL_RGBA || format == GL_BGRA) | ||||
|             && (type == GL_UNSIGNED_SHORT_4_4_4_4 | ||||
|                 || type == GL_UNSIGNED_SHORT_4_4_4_4_REV | ||||
|                 || type == GL_UNSIGNED_SHORT_5_5_5_1 | ||||
|                 || type == GL_UNSIGNED_SHORT_1_5_5_5_REV | ||||
|                 || type == GL_UNSIGNED_INT_8_8_8_8 | ||||
|                 || type == GL_UNSIGNED_INT_8_8_8_8_REV | ||||
|                 || type == GL_UNSIGNED_INT_10_10_10_2 | ||||
|                 || type == GL_UNSIGNED_INT_2_10_10_10_REV), | ||||
|         GL_INVALID_OPERATION); | ||||
| 
 | ||||
|     // FIXME: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
 | ||||
|     //        target and the buffer object's data store is currently mapped.
 | ||||
|     // FIXME: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
 | ||||
|     //        target and the data would be unpacked from the buffer object such that the memory reads required would
 | ||||
|     //        exceed the data store size.
 | ||||
|     // FIXME: GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to the GL_PIXEL_UNPACK_BUFFER
 | ||||
|     //        target and data is not evenly divisible into the number of bytes needed to store in memory a datum
 | ||||
|     //        indicated by type.
 | ||||
| 
 | ||||
|     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 || type != GL_UNSIGNED_BYTE) { | ||||
|         dbgln("gl_draw_pixels: unsupported format {:#x} or type {:#x}", 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 GL_UNPACK_ALIGNMENT and other pixel parameters
 | ||||
|     auto pixel_data = static_cast<u32 const*>(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( | ||||
|         bitmap, | ||||
|         static_cast<int>(m_current_raster_position.window_coordinates.x()), | ||||
|         static_cast<int>(m_current_raster_position.window_coordinates.y())); | ||||
| } | ||||
| 
 | ||||
| void SoftwareGLContext::gl_depth_range(GLdouble min, GLdouble max) | ||||
| { | ||||
|     APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_depth_range, min, max); | ||||
|  | @ -2366,6 +2466,15 @@ void SoftwareGLContext::gl_light_model(GLenum pname, GLfloat x, GLfloat y, GLflo | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void SoftwareGLContext::gl_bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap) | ||||
| { | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| void SoftwareGLContext::present() | ||||
| { | ||||
|     m_rasterizer.blit_to(*m_frontbuffer); | ||||
|  |  | |||
|  | @ -90,6 +90,7 @@ public: | |||
|     virtual void gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) override; | ||||
|     virtual void gl_draw_arrays(GLenum mode, GLint first, GLsizei count) override; | ||||
|     virtual void gl_draw_elements(GLenum mode, GLsizei count, GLenum type, const void* indices) override; | ||||
|     virtual void gl_draw_pixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* data) override; | ||||
|     virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) override; | ||||
|     virtual void gl_get_booleanv(GLenum pname, GLboolean* data) override; | ||||
|     virtual void gl_get_doublev(GLenum pname, GLdouble* params) override; | ||||
|  | @ -113,6 +114,7 @@ public: | |||
|     virtual void gl_push_attrib(GLbitfield mask) override; | ||||
|     virtual void gl_pop_attrib() override; | ||||
|     virtual void gl_light_model(GLenum pname, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override; | ||||
|     virtual void gl_bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap) override; | ||||
|     virtual void present() override; | ||||
| 
 | ||||
| private: | ||||
|  | @ -275,6 +277,7 @@ private: | |||
|             decltype(&SoftwareGLContext::gl_depth_mask), | ||||
|             decltype(&SoftwareGLContext::gl_draw_arrays), | ||||
|             decltype(&SoftwareGLContext::gl_draw_elements), | ||||
|             decltype(&SoftwareGLContext::gl_draw_pixels), | ||||
|             decltype(&SoftwareGLContext::gl_depth_range), | ||||
|             decltype(&SoftwareGLContext::gl_polygon_offset), | ||||
|             decltype(&SoftwareGLContext::gl_scissor), | ||||
|  | @ -286,7 +289,8 @@ private: | |||
|             decltype(&SoftwareGLContext::gl_line_width), | ||||
|             decltype(&SoftwareGLContext::gl_push_attrib), | ||||
|             decltype(&SoftwareGLContext::gl_pop_attrib), | ||||
|             decltype(&SoftwareGLContext::gl_light_model)>; | ||||
|             decltype(&SoftwareGLContext::gl_light_model), | ||||
|             decltype(&SoftwareGLContext::gl_bitmap)>; | ||||
| 
 | ||||
|         using ExtraSavedArguments = Variant< | ||||
|             FloatMatrix4x4>; | ||||
|  |  | |||
|  | @ -604,6 +604,14 @@ void SoftwareRasterizer::clear_depth(float depth) | |||
|     m_depth_buffer->clear(depth); | ||||
| } | ||||
| 
 | ||||
| void SoftwareRasterizer::blit(Gfx::Bitmap const& source, int x, int y) | ||||
| { | ||||
|     wait_for_all_threads(); | ||||
| 
 | ||||
|     Gfx::Painter painter { *m_render_target }; | ||||
|     painter.blit({ x, y }, source, source.rect(), 1.0f, true); | ||||
| } | ||||
| 
 | ||||
| void SoftwareRasterizer::blit_to(Gfx::Bitmap& target) | ||||
| { | ||||
|     wait_for_all_threads(); | ||||
|  |  | |||
|  | @ -61,6 +61,7 @@ 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 wait_for_all_threads() const; | ||||
|     void set_options(const RasterizerOptions&); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jelle Raaijmakers
						Jelle Raaijmakers