Page 1 of 1

RGB Colors 24-bit Help

Posted: Mon Feb 23, 2009 5:34 am
by purage
HI. I have been playing with my VESA driver and everything seems to work fine except when I try to use some colors. I am in a mode using a palette of 24-bit colors and it seems I can only use certain colors, colors that share this pattern: 0xFFFFFF, 0x333333, 0xBBBBBB, etc...

When I use a color like: 0x9FB6CD

All I receive in return is this greyish pixel where the three colors R, G, and B are visible. I can see red, blue, and green points making up one pixel. The colors are not blending together, I suppose is the issue, but I do not know why. Do I need to set the DAC Control function's bits per primary color field after calling function 4f02 or should I be fine without doing that? That is the only thing I can think of.

I am using this function here to plot my pixels:

Code: Select all

void put_pixel(int x,int y, int color)
{
    vbe_info_t vbe;
    char *lfb = (char *)hal.lfb;
    unsigned where=x*3+y*vbe.BytesPerScanLine;
    lfb[where]=color&255;         // BLUE
    lfb[where+1]=(color>>8)&255;  // GREEN
    lfb[where+2]=(color>>16)&255; // RED
}
Any hints as to why my colors are lacking their color? thank you

Re: RGB Colors 24-bit Help

Posted: Mon Feb 23, 2009 10:45 am
by Creature
Isn't the 'where' variable supposed to be something like:

Code: Select all

unsigned where = (y * yourScreenWidth + x) * yourBytesPerPixel;
Tell me if that works.

Re: RGB Colors 24-bit Help

Posted: Mon Feb 23, 2009 12:07 pm
by Brendan
Hi,
Creature wrote:Isn't the 'where' variable supposed to be something like:

Code: Select all

unsigned where = (y * yourScreenWidth + x) * yourBytesPerPixel;
No - the original "x*3+y*vbe.BytesPerScanLine;" is how it's meant to be done.
purage wrote:When I use a color like: 0x9FB6CD

All I receive in return is this greyish pixel where the three colors R, G, and B are visible.
Does it look like a greyish pixel, or does it look like 3 pixels (a red pixel, a green pixel and a blue pixel)?

If it looks like 3 separate pixels, then maybe you're not using 24 bits per pixel. For e.g. maybe it's 8-bits per pixel where each byte is an index into a pallette. In this case 0x333333 might be three grey pixels next to each other that looks like one wide pixel but isn't.

If you are in 24-bpp mode, then the colour 0x9FB6CD would be grey with a slight green/cyan tint. What happens for the colours 0xFF8080 (light red), 0x80FF80 (light green) and 0x8080FF (light blue)? If they work OK, then how about 0xFFFF80 (light orange/yellow), 0xFF80FF (light purple) and 0x80FFFF (light cyan)?

Also note that you should check the "direct color fields" in the "ModeInfoBlock" structure to make sure it's "8:8:8 RGB" and not "8:8:8 BGR" or "7:10:7 RGB" or something else, and check the "MemoryModel" field to make sure it's 0x06 (Direct colour) and not 0x07 (YUV).


Cheers,

Brendan

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 12:05 am
by purage
Hi. I checked those fields and here is the outcome:

Code: Select all

(B)lue Mask Pos = 0
(B)lue Size = 8
(G)reen Mask Pos = 8
(G)reen Size = 8
(R)ed Mask Pos = 16
(R)ed Size = 8

Memory Model = 6 (direct color)

---------------------------------------------------------------------------------

(R)		                  (R)(G)                      (G-B) 	       (B)
23-22-21-20-19-18   |   17-16-15-14-13-12-11-10-9   |   8-7-6-5-4-3-2-1-0

---------------------------------------------------------------------------------

Since we now know that it is not an issue with the put_pixel function, what else could be the issue. When I tried using those values you gave me the result was that I could visibly see the cluster of red, green, and blue points which visually creates a grey pixel.
VBE 2.0: 4.11. Function 08h - Set/Get DAC Palette Format wrote: The DAC palette width is assumed to be reset to the standard VGA value of 6 bits per primary color during any mode set
I tried setting the DAC bits of color per primary to 0x08 (8 bits) after setting the mode, but I still see the same result. Any ideas?

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 3:07 am
by Brendan
Hi,
purage wrote:Since we now know that it is not an issue with the put_pixel function, what else could be the issue.
The only thing I can think of (that hasn't already been ruled out), is that everything is working properly and there is no problem.

Note: Your idea of "working properly" might not be the same as the monitor manufacturer's idea of "working properly"...

Different LCD screens have different pixel layouts. For example, for a cheaper LCD screen pixels might be arranged like this:

Code: Select all

   -----   -----
  |R|B|G| |R|B|G|
  |R|B|G| |R|B|G|
  |R|B|G| |R|B|G|
   -----   -----
A higher quality LCD screen might have pixels arranged like this:

Code: Select all

   -----   -----
  |R|B|G| |GG|RR|
  |R|B|G| |-----|
  |-----| |R|B|G|
  |GG|RR| |R|B|G|
   -----   -----
This arrangement helps to make a pixel look like a single pixel (and not like 3 different coloured dots).

There are other (more complex) arrangements. For some, the little pieces that make up a pixel are determined by what video mode you're using. For example:

Code: Select all

  |-----|-----|
  |R|B|G|BBBBB|
  |R|B|G|-----|
  |-----|GG|RR|
  |GG|RR|-----|
  |-----|R|B|G|
  |BBBBB|R|B|G|
  |-----|-----|
Which could be used as 4 separate pixels like this:

Code: Select all

   -----   -----
  |R|B|G| |BBBBB|
  |R|B|G| |-----|
  |-----| |GG|RR|
   -----   -----

   -----   -----
  |GG|RR| |-----|
  |-----| |R|B|G|
  |BBBBB| |R|B|G|
   -----   -----
Or, 2 separate (wide) pixels like this:

Code: Select all

   ----- -----
  |R|B|G|BBBBB|
  |R|B|G|-----|
  |-----|GG|RR|
   ----- -----

   ----- -----
  |GG|RR|-----|
  |-----|R|B|G|
  |BBBBB|R|B|G|
   ----- -----
Or, 2 separate (narrow) pixels like this:

Code: Select all

   -----   -----
  |R|B|G| |BBBBB|
  |R|B|G| |-----|
  |-----| |GG|RR|
  |GG|RR| |-----|
  |-----| |R|B|G|
  |BBBBB| |R|B|G|
   -----   -----
For CRTs, pixels are typically grouped in triangles, like this:

Code: Select all

   O  0 0  O
  O O  0  O O
In all cases, if you use a video mode with a smaller resolution that the native/maximum resolution you end up with scaling, where a (small) picture is stretched across the (larger) screen. This helps to hide the little pieces that make up a pixel too. Note: for CRT monitors the picture is only scaled in the horizontal direction and this scaling is a natural consequence of the technology used. For LCD screens the scaling happens in both directions and is done by special electronics/software inside the monitor.

Also, for a tiny LCD screen that supports a maximum resolution of (for e.g.) 1680 * 1050 the pieces that make up a pixel would be extremely small and harder to see, while a huge LCD screen that supports the same maximum resolution (and same pixel layout) would have much larger pieces that make up a pixel that are easier to see.

Basically, my guess is that you're using a large LCD screen (that was cheaper than other LCD screens with the same size and same maximum resolution) and that the video mode is close to the maximum resolution of the monitor.


Cheers,

Brendan

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 3:12 am
by Brendan
Hi,

Doh, I forgot to mention...
purage wrote:
VBE 2.0: 4.11. Function 08h - Set/Get DAC Palette Format wrote: The DAC palette width is assumed to be reset to the standard VGA value of 6 bits per primary color during any mode set
I tried setting the DAC bits of color per primary to 0x08 (8 bits) after setting the mode, but I still see the same result. Any ideas?
The palette is only ever used by 256 colour modes, 16 colour modes, 4 colour modes and monochome modes (8-bit, 4-bit, 2-bit and 1-bit). For these modes the value you set for a pixel is used as an index into a lookup table (the palette), and the values in the lookup table/palette are what is sent to the monitor. For direct colour, the colour comes directly from the value you put in the pixel (the palette isn't used at all).


Cheers,

Brendan

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 11:12 am
by Dex
Just in case some use RGBRGB etc at this mode and some use xRGBxRGB etc
Check "ModeInfo_BitsPerPixel" to see if its 24 or 32

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 5:18 pm
by purage
Brendan, Dex: Thank you both for responding to this thread. I tried all night to log in and tell you that I got it working, but I was unable to due to some sort of network problems. At least now you have made this thread a valuable resource for others following behind us. Anyway The problem was the most ridiculous of all as I wasn't even looking at that line. In the put_pixel code I changed:

unsigned where=x*3+y*vbe.BytesPerScanLine;

to

unsigned where=x*4+y*vbe.BytesPerScanLine;

And, it worked. I can now draw pixels with color other than grey! I am not sure yet how to figure out that value from the bitsperpixel value. I saw in the wiki that it gets shifted to the right by 3, but when I tried that I got nothing. Maybe divide by 5 and the decimal drops? Anyway, I am glad I finally got it working. Thanks a lot for your help. take care

Re: RGB Colors 24-bit Help

Posted: Tue Feb 24, 2009 5:40 pm
by Firestryke31
The actual equation for figuring out the linear index of a pixel in a 2D image is this:

x * bitsPerPixel / 8 + y * bytesPerLine;

It's divided by 8 due to the fact that there are 8 bits in a byte.

24 / 8 = 3
32 / 8 = 4
4 / 8 = .5
etc.

So you can see that this works for any bit depth (though you'll need some code to handle advancing part of a byte if you want bit depths less than 8 ).