Page 1 of 1
PutPixel & GUI Sharing
Posted: Fri Jan 23, 2009 4:16 pm
by sweetgum
I have a question and I'd be interested in seeing everyones methods of Drawing Graphics, this is where i am at my os, its time to design a UI
The wiki shows this example,
Code: Select all
/* only valid for 800x600x16M */
static void putpixel(unsigned char* screen, int x,int y, int color)
{
unsigned where=x*3+y*2400;
screen[where]=color&255; // BLUE
screen[where+1]=(color>>8)&255; // GREEN
screen[where+2]=(color>>16)&255; // RED
}
/* only valid for 800x600x32bpp */
static void putpixel(unsigned char* screen, int x,int y, int color)
{
unsigned where=x*4+y*3200;
screen[where]=color&255; // BLUE
screen[where+1]=(color>>8)&255; // GREEN
screen[where+2]=(color>>16)&255; // RED
}
Is screen supposed to be a pointer to 0xB8000? If not, what is it?
Re: PutPixel & GUI Sharing
Posted: Fri Jan 23, 2009 5:42 pm
by Combuster
B8000 is the set default for text mode. VGA graphics mode starts at A0000. VESA with LFB can have the video memory practically anywhere (and since VGA doesn't support 24 bit colors, its either VESA or a device-specific driver)
that should be enough to start you google tours
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 5:40 am
by jal
sweetgum wrote:this is where i am at my os, its time to design a UI
You mean your OS has virtual memory through paging, a fully fledged VFS with support for FAT, ext2 etc., a USB stack, network stack, program loading, relocating and executing, drivers for most common hardware, and all that? That's pretty neat. If not, I'd seriously consider creating all that, before trying a GUI. On the other hand, if you like creating GUIs, but not writing OSes, you can always create a window manager for Linux.
JAL
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 9:37 am
by Creature
When I had my graphics (which I recently ditched from my OS since I decided it was crowding everything, didn't work on a real PC and that my OS wasn't ready for it), I did something like this:
Code: Select all
//Where 'Surface' is a crazy structure containing the video memory pointer and some information about the surface.
void DrawPixel(Surface *Surf, short X, short Y, unsigned Col)
{
//Where BytesPerPixel = BitsPerPixel / 8
byte *Pixel = Surf->Data[(Y * Surf->Width + X) * Surf->BytesPerPixel];
switch(Surf->BytesPerPixel)
{
case 1:
//8 BPP, address Pixel as a byte and set the colour.
break;
case 2:
//16 BPP, address Pixel as a word and set the colour.
break;
case 3:
//24 BPP, address the RGB components individually.
//Convert Col (hexcolour) to an RGB colour and do something like:
//Pixel[0] = Col.R;
//Pixel[1] = Col.G;
//Pixel[2] = Col.B;
//Of course this possibly depends on endianness.
break;
case 4:
//32 BPP, address Pixel as a qword and set the colour.
break;
}
}
You've probably noticed 15 BPP is missing, but at that time I figured I'd never use it and implement it later if necessary. It's been a while since I coded this, so there are probably some mistakes which I didn't have in the actual code. Those of you who know SDL, probably know that it also has
documentation on this kind of thing. Note that this documentation is intended for SDL, but the principle on your OS is the same.
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 9:44 am
by giszo
jal wrote:sweetgum wrote:this is where i am at my os, its time to design a UI
You mean your OS has virtual memory through paging, a fully fledged VFS with support for FAT, ext2 etc., a USB stack, network stack, program loading, relocating and executing, drivers for most common hardware, and all that? That's pretty neat. If not, I'd seriously consider creating all that, before trying a GUI. On the other hand, if you like creating GUIs, but not writing OSes, you can always create a window manager for Linux.
JAL
Why is a network stack or an USB stack required to create a (simple) GUI?
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 10:21 am
by jal
giszo wrote:Why is a network stack or an USB stack required to create a (simple) GUI? :)
Of course it isn't (although a USB stack may get in handy for natively handling USB mice), but it just struck me as if the OP had just written (copied?) a boot loader, and wanted to start a GUI as project #2. Which, as we all know, is a bit silly.
JAL
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 11:39 am
by tantrikwizard
sweetgum wrote:Is screen supposed to be a pointer to 0xB8000? If not, what is it?
screen is the start address of video memory. It could be in several places. Use VBE Enumerate the supported video modes and pick the one you want. Tell VESA to use a LFB (linear frame buffer) for video memory and get the memory address for the resolution mode.
These PutPixel routines might not work on all video cards even when using the specified resolution. According to the VBE spec you should set the pixel bits according to the mode info block. The mode info block will specify the number of bits per color per pixel and their offsets. These assume the mode is set which accepts RRGGBB per pixel. This is acceptable for theory but in practice more is required.
Re: PutPixel & GUI Sharing
Posted: Mon Jan 26, 2009 2:39 pm
by Creature
berkus wrote:Creature wrote:When I had my graphics (which I recently ditched from my OS since I decided it was crowding everything, didn't work on a real PC and that my OS wasn't ready for it), I did something like this:
Would be sort of faster to have DrawPixel15, DrawPixel16, DrawPixel24, DrawPixel32 etc functions and after setting mode, set corresponding function pointers in any information structure (Surface itself would do, btw) to point to the appropriate function for Surface's bit depth.
Also, PutPixel alone is rather inefficient and crude method, go for whole lines, (filled) rectangles and optimized bit blits.
See Hermes/ClanLib/agg/(Tiny|Open)PTC and other fast graphics libraries for examples on how to do it best.
Yes, that's true, it was just some sort of general function that could handle most of the BPP's at the same time. I realize that if you have to fill the entire screen with this method, it'd check the BPP 480000 times (on a 800x600 screen, for each pixel), which means 479999 times are useless
.