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
 | // Source pixel data format
 | ||||||
| #define GL_UNSIGNED_BYTE 0x1401 | #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
 | // Stencil buffer operations
 | ||||||
| #define GL_KEEP 0x1E00 | #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 glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); | ||||||
| GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count); | GLAPI void glDrawArrays(GLenum mode, GLint first, GLsizei count); | ||||||
| GLAPI void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); | 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 glDepthRange(GLdouble nearVal, GLdouble farVal); | ||||||
| GLAPI void glDepthFunc(GLenum func); | GLAPI void glDepthFunc(GLenum func); | ||||||
| GLAPI void glPolygonMode(GLenum face, GLenum mode); | 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 glLineWidth(GLfloat width); | ||||||
| GLAPI void glPushAttrib(GLbitfield mask); | GLAPI void glPushAttrib(GLbitfield mask); | ||||||
| GLAPI void glPopAttrib(); | GLAPI void glPopAttrib(); | ||||||
|  | GLAPI void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const* bitmap); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #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_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_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_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_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_booleanv(GLenum pname, GLboolean* data) = 0; | ||||||
|     virtual void gl_get_doublev(GLenum pname, GLdouble* params) = 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_push_attrib(GLbitfield mask) = 0; | ||||||
|     virtual void gl_pop_attrib() = 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_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; |     virtual void present() = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -9,6 +9,16 @@ | ||||||
| 
 | 
 | ||||||
| extern GL::GLContext* g_gl_context; | 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) | void glLineWidth(GLfloat width) | ||||||
| { | { | ||||||
|     g_gl_context->gl_line_width(width); |     g_gl_context->gl_line_width(width); | ||||||
|  |  | ||||||
|  | @ -1926,6 +1926,106 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type | ||||||
|     glEnd(); |     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) | void SoftwareGLContext::gl_depth_range(GLdouble min, GLdouble max) | ||||||
| { | { | ||||||
|     APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_depth_range, min, 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() | void SoftwareGLContext::present() | ||||||
| { | { | ||||||
|     m_rasterizer.blit_to(*m_frontbuffer); |     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_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_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_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_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_booleanv(GLenum pname, GLboolean* data) override; | ||||||
|     virtual void gl_get_doublev(GLenum pname, GLdouble* params) 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_push_attrib(GLbitfield mask) override; | ||||||
|     virtual void gl_pop_attrib() 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_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; |     virtual void present() override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -275,6 +277,7 @@ private: | ||||||
|             decltype(&SoftwareGLContext::gl_depth_mask), |             decltype(&SoftwareGLContext::gl_depth_mask), | ||||||
|             decltype(&SoftwareGLContext::gl_draw_arrays), |             decltype(&SoftwareGLContext::gl_draw_arrays), | ||||||
|             decltype(&SoftwareGLContext::gl_draw_elements), |             decltype(&SoftwareGLContext::gl_draw_elements), | ||||||
|  |             decltype(&SoftwareGLContext::gl_draw_pixels), | ||||||
|             decltype(&SoftwareGLContext::gl_depth_range), |             decltype(&SoftwareGLContext::gl_depth_range), | ||||||
|             decltype(&SoftwareGLContext::gl_polygon_offset), |             decltype(&SoftwareGLContext::gl_polygon_offset), | ||||||
|             decltype(&SoftwareGLContext::gl_scissor), |             decltype(&SoftwareGLContext::gl_scissor), | ||||||
|  | @ -286,7 +289,8 @@ private: | ||||||
|             decltype(&SoftwareGLContext::gl_line_width), |             decltype(&SoftwareGLContext::gl_line_width), | ||||||
|             decltype(&SoftwareGLContext::gl_push_attrib), |             decltype(&SoftwareGLContext::gl_push_attrib), | ||||||
|             decltype(&SoftwareGLContext::gl_pop_attrib), |             decltype(&SoftwareGLContext::gl_pop_attrib), | ||||||
|             decltype(&SoftwareGLContext::gl_light_model)>; |             decltype(&SoftwareGLContext::gl_light_model), | ||||||
|  |             decltype(&SoftwareGLContext::gl_bitmap)>; | ||||||
| 
 | 
 | ||||||
|         using ExtraSavedArguments = Variant< |         using ExtraSavedArguments = Variant< | ||||||
|             FloatMatrix4x4>; |             FloatMatrix4x4>; | ||||||
|  |  | ||||||
|  | @ -604,6 +604,14 @@ void SoftwareRasterizer::clear_depth(float depth) | ||||||
|     m_depth_buffer->clear(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) | void SoftwareRasterizer::blit_to(Gfx::Bitmap& target) | ||||||
| { | { | ||||||
|     wait_for_all_threads(); |     wait_for_all_threads(); | ||||||
|  |  | ||||||
|  | @ -61,6 +61,7 @@ public: | ||||||
|     void resize(const Gfx::IntSize& min_size); |     void resize(const Gfx::IntSize& min_size); | ||||||
|     void clear_color(const FloatVector4&); |     void clear_color(const FloatVector4&); | ||||||
|     void clear_depth(float); |     void clear_depth(float); | ||||||
|  |     void blit(Gfx::Bitmap const&, int x, int y); | ||||||
|     void blit_to(Gfx::Bitmap&); |     void blit_to(Gfx::Bitmap&); | ||||||
|     void wait_for_all_threads() const; |     void wait_for_all_threads() const; | ||||||
|     void set_options(const RasterizerOptions&); |     void set_options(const RasterizerOptions&); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jelle Raaijmakers
						Jelle Raaijmakers