Browse Source

LibGL+LibSoftGPU: Add support for 8-bit luminance (+ alpha) textures

Used by Half-Life for single colour textures. The alpha variant is
especially used for UI textures.
Luke Wilde 3 years ago
parent
commit
c6a0365c58

+ 2 - 0
Userland/Libraries/LibGL/GL/gl.h

@@ -239,7 +239,9 @@ extern "C" {
 #define GL_RGB 0x1907
 #define GL_RGBA 0x1908
 #define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE8 0x8040
 #define GL_LUMINANCE_ALPHA 0x190A
+#define GL_LUMINANCE8_ALPHA8 0x8045
 #define GL_BGR 0x190B
 #define GL_BGRA 0x190C
 #define GL_BITMAP 0x1A00

+ 9 - 1
Userland/Libraries/LibGL/SoftwareGLContext.cpp

@@ -915,7 +915,7 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern
         internal_format = GL_RGBA;
 
     // We only support symbolic constants for now
-    RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA), GL_INVALID_ENUM);
+    RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA || internal_format == GL_LUMINANCE8 || internal_format == GL_LUMINANCE8_ALPHA8), GL_INVALID_ENUM);
     RETURN_WITH_ERROR_IF(!(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_6_5), GL_INVALID_VALUE);
     RETURN_WITH_ERROR_IF(level < 0 || level > Texture2D::LOG2_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
     RETURN_WITH_ERROR_IF(width < 0 || height < 0 || width > (2 + Texture2D::MAX_TEXTURE_SIZE) || height > (2 + Texture2D::MAX_TEXTURE_SIZE), GL_INVALID_VALUE);
@@ -941,6 +941,14 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern
             device_format = SoftGPU::ImageFormat::RGBA8888;
             break;
 
+        case GL_LUMINANCE8:
+            device_format = SoftGPU::ImageFormat::L8;
+            break;
+
+        case GL_LUMINANCE8_ALPHA8:
+            device_format = SoftGPU::ImageFormat::L8A8;
+            break;
+
         default:
             VERIFY_NOT_REACHED();
         }

+ 32 - 0
Userland/Libraries/LibSoftGPU/ImageFormat.h

@@ -16,12 +16,17 @@ enum class ImageFormat {
     BGR888,
     RGBA8888,
     BGRA8888,
+    L8,
+    L8A8,
 };
 
 inline static constexpr size_t element_size(ImageFormat format)
 {
     switch (format) {
+    case ImageFormat::L8:
+        return 1;
     case ImageFormat::RGB565:
+    case ImageFormat::L8A8:
         return 2;
     case ImageFormat::RGB888:
     case ImageFormat::BGR888:
@@ -83,6 +88,26 @@ inline static FloatVector4 unpack_color(void const* ptr, ImageFormat format)
             1.0f
         };
     }
+    case ImageFormat::L8: {
+        auto luminance = *reinterpret_cast<u8 const*>(ptr);
+        auto clamped_luminance = luminance * one_over_255;
+        return {
+            clamped_luminance,
+            clamped_luminance,
+            clamped_luminance,
+            1.0f,
+        };
+    }
+    case ImageFormat::L8A8: {
+        auto luminance_and_alpha = reinterpret_cast<u8 const*>(ptr);
+        auto clamped_luminance = luminance_and_alpha[0] * one_over_255;
+        return {
+            clamped_luminance,
+            clamped_luminance,
+            clamped_luminance,
+            luminance_and_alpha[1] * one_over_255,
+        };
+    }
     default:
         VERIFY_NOT_REACHED();
     }
@@ -115,6 +140,13 @@ inline static void pack_color(FloatVector4 const& color, void* ptr, ImageFormat
     case ImageFormat::RGB565:
         *reinterpret_cast<u16*>(ptr) = (r & 0x1f) | ((g & 0x3f) << 5) | ((b & 0x1f) << 11);
         return;
+    case ImageFormat::L8:
+        *reinterpret_cast<u8*>(ptr) = r;
+        return;
+    case ImageFormat::L8A8:
+        reinterpret_cast<u8*>(ptr)[0] = r;
+        reinterpret_cast<u8*>(ptr)[1] = a;
+        return;
     default:
         VERIFY_NOT_REACHED();
     }