Search code examples
c++operating-systempixel

How to divide Pixels in Subpixels?


I am Developing an OS, I have to Subdivide Pixels into Subpixels, I am Using GOP Framebuffers https://wiki.osdev.org/GOP ,

Is it Possible to Subdivide Pixels in GOP Framebuffers?

How can I do it?

I Found these only on Internet :

Subpixel Rendering : https://en.wikipedia.org/wiki/Subpixel_rendering

Subpixel Resolution : https://en.wikipedia.org/wiki/Sub-pixel_resolution

The Most useful : https://www.grc.com/ct/ctwhat.htm

How can I Implement It in My OS?


Solution

  • How can I Implement It in My OS?

    The first step is to determine the pixel geometry (see https://en.wikipedia.org/wiki/Pixel_geometry ); because if you don't know that any attempt at sub-pixel rendering is likely to just make the image worse than not doing sub-pixel rendering at all. I've never been able to find a sane way to obtain this information. A "least insane" way is to get the monitor's EDID/E-EDID (Extended Display Identification Data - see https://en.wikipedia.org/wiki/Extended_Display_Identification_Data ), extract the manufacturer and product code, and then use manufacturer and product code to find the information somewhere elsewhere (from a file, from a database, ..). Sadly this means that you'll have to create all the information needed for all monitors you support (and fall back to "sub-pixel rendering disabled" for unknown monitors).

    Note: As an alternative; you can let the user set the pixel geometry; but most users won't know and won't want the hassle, and the rest of users will set it wrong, so...

    The second step is the make sure you're using the monitor's preferred resolution; because if you're not then the monitor will probably be scaling your image to make it fit and that will destroy any benefit of sub-pixel rendering. To do this you want to obtain and parse the monitors EDID or E-EDID data and try to determine the preferred resolution; then use the preferred resolution when setting the video mode. Unfortunately some monitors (mostly old stuff) either won't tell you the preferred resolution or won't have a preferred resolution; and if you can determine the preferred resolution you might not be able to set that video mode with VBE (on BIOS) or GOP or UGA (on UEFI), and writing native video drivers is "not without further problems".

    The third step is the actual rendering; but that depends on how you're rendering what.

    For advanced rendering (capable of 3D - textured polygons, etc) it's easiest to think of it as rendering separate monochrome images (e.g. one for red, one for green, one for blue) with a slight shift in the camera's position to reflect the pixel geometry. For example, if the pixel geometry is "3 vertical bars, with red on the left of the pixel, green in the middle and blue on the right" then when rendering the red monochrome image you'd shift the camera slightly to the left (by about a third of a pixel). However, this almost triples the cost of rendering.

    If you're only doing sub-pixel rendering for fonts then it's the same basic principle in a much more limited setting (when rendering fonts to a texture/bitmap and not when rendering anything to the screen). In this case, if you cache the resulting pixel data and recycle it (which you'll want to do anyway) it can have minimal overhead. This requires that the text being rendered is aligned to a pixel grid (and not scaled in any way, or at abitrary angles, or stuck onto the side of a spinning 3D teapot, or anything like that).