FireNet 64 Posting Whiz in Training
Graphics In Pixel
				     Part II A
			  'Now we are going to get it'

                              By Aaron (a.k.a FireNet)
                             [url]http://xlock.hostcubix.com[/url]

Introduction
-------------
The long awaited part 2 is finally almost here.This is mini section elaborates on
what Part I said.I broke up up Part II because it was getting too long.
Reasons, nothing much, I was very busy working on my site and developing video interfaces. A good thing too, I learnt and discovered a lot of things over a vast verity of graphics related subjects.You guys are going to benift from it in part 3.Here we will go over and above what we did last time.

Tutorial Source and Pics (Policy Stuff)
------------------------------------
Since it is against the policy of http://xlock.hostcubix.com to allow
linking of files and images directly I cannot place them on this page.To
get your source downloads/see pics/revised versions/etc for this series please visit:
http://xlock.hostcubix.com/cgi-bin/lwton.cgi?page=tutGRP

Other than that enjoy.

Language:C++
Compilers:Borland C++ 5.x, DJGPP 3.x
Date:2nd Spetember 2004
Site:http://xlock.hostcubix.com/

Setting the Mode with an understanding
---------------------------------------
Now let me explain what mode13h is all about.I did this last time so reffer that too.Every thing we see on a computer screen is made up of pixel, these are tiny dots, square ones (I think) and these are of diffrent colors, which give an image of all we see on the screen.Now if we could draw pixel by pixel then we could make any shape which we want and the major problem is we dont know how............

Mode13h provides us with a very simple way by which to draw to the screen.In the video hardware(i.e video card) all the colors we see on screen are stored in it's memory.Entering mode13h allows us to change these values,hence changing the pixels on the screen (Basically,there is some OS and hardware game is going on beneath but in essence this is what happens.)

Ok, I will say what goes on with the screen hardware.In you crt screens, there is an electron gun which is used to well show color on the screen, just like a TV.This gun reads off the info from video card memory and puts it to the screen.Going from top to down or down to top.I am not really sure,but it will only draw while it's going in one direction either up or down.The period in which the gun draws nothing is called the vertical retrace.

With Mode13h you can write directly to the video memory which is at a fixed location of 0xA0000.You can write starting from that location just like a char array.Each pixel is represented by 1 byte, which is the same as the size of a char.

The Mode13h screen is 320 pixel wide and 200 pixels high.It has only 256 colors i.e 0-255 which can be represented with 1 byte.

Now before you can start using that address, you will have to tell you computer you want go into mode13h.There are a couple of way to do that, the fastest being in ASM, but since this is a C++ tut,I will give the C++ version.

The code is same for both Borland and DJGPP

#include <dos.h>

void SetMode13h()
{
	union REGS r;		// A make-believe software register
	r.h.ah = 0x00;		// BIOS VGA screenmode changing function
	r.h.al = 0x13;		// 0x13 means mode13h
	int86(0x10, &r, &r);	// Call int 0x10 with the info we supplied
}

0x00 is the BIOS funtion for setting a graphics mode.0x13 represents mode13h
graphics mode.0x10 is the BIOS video interrupt.An interupt actually causes the computer to stop what ever it is doing and handle your request.We will leave it at that.The above code will make you computer to put it's screen into mode13h. And then you are free to usw the VGA memory address to do what ever you want.

This was a detailed explanation of what was covered in Part I.Hope understood this.Now that you have entered mode13h let's go to putting pixels on the screen.

Pegging Pixels on the Screen
----------------------------
Now how do you do that? I mentioned before the screen memory is a linear buffer with each pixel being of 1 byte.The first pixel is at 0, the second at 1, the 3rd at 2 and so on and so forth.How's that is code?

vga_screen = 0xA00000;
	
	//To put the first pixel
	vag_screen[0]	= 1;
	
	//To put the second pixel
	vag_screen[2]	= 1;
	
	//To fill an entire line at the top,
	//well the screen is 320 pixel wide, so we have to fill 320 pixel;
	for(int i=0;i<320;i++)
	{
		vga_screen[i] = 2;	//Green color ,right?
	}

Cool,we did a line.Let's see what happens if we increase the size of the line by 1. Try it.See it? A pixel appeared on the next line.

That's how we are going to put pixel in an x,y location.0,0 will be at the left
hand top corner.So if we want to put a pixel at 0,1 i.e the beggining of
the second line we can calculate the location offset by:

offset = y*320+x;
	vga_screen[offset] = color;

320 is the width of the screen.

Simple eh?.I don think I want to bore you will further explanation.If you have not got yet, think again and you will understand.

Now there's a faster way of calculating a pixel offset using bit shifts.Shifting bit to the left give the effect of multipling by 2 and shifting right gives the effect of dividing by 2.

num << 1 = num * 2;

So the way to calculate the offset using bit shifts is:

vga_screen[(y<<8)+(y<<6)+x] = color;

Here's how the calcuations go.

y<<8 + y<<6 + x
-------------------
 y*2^8 + y*2^6 + x			^ means raised to the power of
--------------------
 y*256 + y*64 +x
--------------------
 y*320 + x

See it work out to the old formula.Bit shifts are faster than multiplication.It wont hurt to optimise such a simple thing which will be called so often.

Fishing Lines, Cloth Lines, Life Lines, Lines
----------------------------------------
Ah something we see everywhere.So simple so straight so easy to draw, for us.Now how do we tell a computer to do that?.We coverded horizontal and vertical lines in Part I of this series ,that was easy enough right?

Now let's try that for arbitary lines.There's a math formula for the defines a line

y = m*x + c

M stands for the slope.So the formula says the y equals slope of line multiplied by the x plus the y intercept.Y-intercept is where x crosses the y-axis.This stuff comes under coordinate geometry.Look futher in higher secondary school math text books.I would recommend it, the stuff is really intersting if you look at it logically and without dislike. That will help you when it comes to more advanced stuff in 3D, graphics programming is all about math.I just love geometry and algebra but I hate the way it's taught somethimes.

Ok back to lines,first the slope (m) so let's look how we can calculate it.

slope = Delta Y / Delta X 
	delta X = x2-x1
	delta Y = y2-y1

x1,y1 are the coordinates of the starting point of the line and x2,y2 are the ending ones Now if we take the slope we will usually get it in fractions which we cannot draw on the screen (why? figure it out, I mean like if the screen looks like a chessbord and you can only put pieces on the squares , were will you put a piece (5.6,4) ?).

Any way what we see on the screen is on very real illusion.Everything we see on screen is made up of dots.One way to see this is to hold a magnifing glass against your monitor (note:I did not try this ;)) or on a picture on a newspaper (ok I tried this, you can also just use your eyes and look closely).We will be able to see the entire thing is made up of tiny dots.If we magnify it even more, one dot will become 3 dots of the colors red,green and
blue.Changing intensities of these (red,green,blue dots) diffrent colors are formed.
So therefore if we magnify a line on a comp screen we can see it's only an approximate one.Try using paint to draw a line and then magnify it.See what I mean?So we will have to round if off to the nearest pixel

Ok now anyway we have the slope, which tells us by how much the y coordinate increases for every x coordinate.So let's put that into something workable.

for the length (x1 to x2) of the line
	{
		PutPixel(x,(int)y,color)		//Y is float, converting it to int explicitly
		y = y + slope
		x++
	}

The thing that happens when the float variable y is converted to int is that all the decimal points vanish.So 10.34 becomes 10 and 10.77 also becomes 10.That means the y axis coordinate will only change when it the x coordinate has increased to such an extent that it produces at least a unit change in the y coordinate.(confusing? gee, this is the simplest consise way I could put what goes on in that loop.).Basically this is what the line will end up looking like.

[][][]
			[][][]
				[][][]

The above thing will work ok if the slope is greater than zero ( > 0) and less than 1 ( < 1). If it is more the line breaks up as you can see if you try it out.(See the example programs).We can fix that though quite easily.If the slope is greater than 1 we will calculate the plotting according to the x-axis instead of the y-axis.So we will have to calculate the slope according to the x-axis.Simple and for the rest just replace x with y and vice-versa

slope = Delta X / Delta Y
	
	for the height (y1 to y2) of the line
	{
		PutPixel((int)x,y,color)		//Y is float, converting it to int explicitly
		y++
		x = x + slope
	}

And voila the lines look so much better.Oh and btw the x and y initial values are x1 and y1 respectively and in the concerned area.Yeeeha we have done it, our very own line algorithm which can draw arbitary lines.Come on, grap the best rock music off your collection and pop it into the cd drive and play.Let's dance.Yea the music's cool.

We just finished a very simple and a bit inefficient line drawing algorithm.This is because we are using floats,calling the put pixel funtion,typecasting from float to int .....for every dot in the line.Yoooo.That ok's but we can improve it a lot.We will disscuss something called the Bresenham's line algorithm which will only use integers next time.

Also there's a small problem if the starting point is after the ending point in real coordinate values.Like a line 10,10 to 100,230 is ok and the same thing 100,230 to 10,10 is not ok with the computer.So you will have to swap the end and start points if the non-slope part of the end coordinate is lesser than the that of the start coordinate.By non-slope mean the part of the coordinate which is not incremented by the slope.Eg in the first part the slope was added
to Y so X is the non-slope apart and in the second part similarly Y is the non-slope part.

Conclusion
-----------
That's it for this edition.Next time we will discuss Bresenhams's algorithms and also circles double buffering and simple animation.Till next time.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.