Lesson 8
- BGI Graphics

If you feel that Graphics is not important for you than skip to lesson 9 (File Handling). BGI Graphics is an advanced topic and need not be explicitly covered. It depends on your preference. Graphics lovers will surely be interested in this topic.

This lesson will cover:

One might require the file egavga.bgi during this graphics tutorial. Click here if you don't have this file (or it is corrupt) and place it in the BGI directory in the Turbo Pascal installation folder.

COPYRIGHT NOTICE: It is assumed that you have bought Turbo Pascal once you have downloaded this file. This file is owned by its respective owners (Borland Company).

IMPORTANT DISCLAIMER: You will download and use this file at your own risk. We don't take any responsability for any damage whatsoever.

Introduction to Graphics

Graphics is a method of representing output material in a more complex, user-friendlier way than the crt. The crt is one of the few turbo pascal units or libraries. Turbo Pascal has a graphics library with which you can represent output material. Before you can call turbo pascal's graphics procedures and functions, you have to include the Graph unit in the Uses section (Eg. Uses Crt, Graph, Overlay, Printers etc...).

Initialising Graphics

Unlike the crt, graphics should be initialised, and it should be initialised at the beginning of the program or just before you start using graphics procedures and functions. This will help the compiler to link to the graphics file. Usually, the default graphics routines used by the Turbo Pascal's compiler is the EGAVGA.BGI. When you initialise the graphics, automatically your computer will use this file to output graphics material.

The famous piece of code, used to initialise the graphics in Turbo Pascal (NOT Dev-PASCAL! Mind you! Dev-Pascal does not accept the graph driver and graph mode be declared as integer values. If you have Dev-Pascal then change all the variable types of the 'gd,gm' to smallint! 'Gd, Gm : Smallint;') is shown below:

 ```Program Lesson8_Program1; Uses Crt,Graph;``` ```Var GraphicsDriver, GraphicsMode, ErrCode : Integer; {two var's are needed for initialisation}``` ```Begin Writeln('Initialising Graphics, please wait...'); GraphicsDriver := Detect; InitGraph(GraphicsDriver, GraphicsMode,''); {IMPORTANT, read the following or otherwise graphics will not work!! ;)} (*between the inverted commas, type in the path of the graphics BGI file (usually 'C:\TP\BGI'), OR change the dir in the file menu (PRESS Alt+F) and roll down your mouse pointer to the 'change dir' menu; then either type the path to the BGI file, or go to C: -> TP -> BGI*) ErrCode := GraphResult; If GraphResult <> grOK then { <> means 'not equal to' } Begin ClrScr; Writeln('Graphics error occured: ', GraphErrorMsg(ErrCode)); Writeln('If a file not found error is displayed above'); Writeln('then, change the dir from the current'); Writeln('location to C:\ -> TP -> BGI, '+ +'from the file menu!'); Readln; Halt(1); End Else Begin Randomize; SetColor(Random(15) + 1); {Set text colour} {Output text at 20 pixels from the top of the screen, and 20 other from the left side of the screen.} OutTextXY(20,20,'Welcome to the new generation of Pascal Programming:'); OutTextXY(20,30,'Pascal Graphics!!'); OutTextXY(25,70,'You will learn more graphics procedures and'); OutTextXY(25,80,'functions, later in this lesson :-)'); Readln; End; CloseGraph; End.```

The program above uses the statement:

InitGraph(GraphicsDriver,GraphicsMode,'');

You may find it strange what does the two inverted commas (' ') mean, in the statement shown above. It is the path which redirects the turbo pascal linker to the graphics BGI file. So, in between the inverted commas, you have to enter the path to the graphics driver, or otherwise you will receive an error message. You may leave it blank and let the compiler himself find the BGI file automatically (in the current directory), but when I did this, it never worked!! :-) If you did not change the folder address (C:\TP) after the installation, you may use this path: 'C:\TP\BGI', like this:

InitGraph(GraphicsDriver,GraphicsMode,'C:\TP\BGI');

After the 'initgraph()' statement, you should inform the user with the problem concerning a graphics error, if the EGAVGA.BGI file is not found. Hope it does not happen to you :-) !! Then, if the user is error-free, then you can start calling graphics procedures and functions from the graphics library (graph). In the example program above, I used only the 'OutTextXY()' statement and the 'SetColor()' statement. However there are many more functions other than these!

At the end of each graphic statments, you have to close the graphics section, by using the 'CloseGraph' statement.

USEFUL INFORMATION:

Note that the screen resolution is 640 by 480 pixels (compare this with that of the CRT! - the CRT has a screen resolution of 80 by 25 'pixels' only!)

Graphics Statements

Learning graphics, is very simple - all you have to learn is how to initialise graphics and then use your graphics knowledge to display whatever you want! Now, the following statements are found in the graph unit which are used to output graphically. Then I will show you an example program using the graph unit, to demonstrate how the statments below work:

 Statement Description Example SetBkColor(colour/colour code); This will set the background colour of the screen to the colour indicated within the parenthesis. SetBkColor(Brown); or SetBkColor(6); SetColor(colour/colour code); This will set the text colour to the colour indicated within the parenthesis. SetColor(Green); or SetColor(2); OutText(''); This statement will output the text indicated within the inverted commas. OutText('BGI Graphics'); OutTextXY(X,Y,''); This is very similar to the one before this statement, except in that it move the cursor position indicated as shown OutTextXY(300,100,'BGI Graphics'); MoveTo(X,Y); Takes the cursor position to that indicated in the brackets. MoveTo(GetMaxX,GetMaxY); PutPixel(X,Y,colour/colour code); Places a small pixel at X pixels left and Y pixels down. PutPixel(50,128,Cyan); or PutPixel(50,128,5); Line(X,Y); Draws a line from the position of the cursor to X, Y. Line(30,111); LineTo(X1,Y1,X2,Y2); Draws a line from X1, Y1 to X2, Y2. LineTo(0,0, GetMaxX,GetMaxY); Rectangle(X1,Y1,X2,Y2); Draws a rectangle from point X1, Y1 to point X2, Y2. Rectangle(30,50,25,45); Circle(X,Y,Radius); Draws a circle from point X, Y with a radius length of Radius. Circle(GetMaxX Div 2, GetMaxY Div 2, 100); Ellipse(X,Y,P,Q,HorR,VerR); Draws an ellipse with centre point X,Y starting from P degrees to Q degrees, with a horizontal radius of HorR and a vertical radius of VerR. Ellipse(300,160, 0,360,60,40); Arc(X,Y,P,Q,Radius); Draws an arc starting from X,Y starting with an angle of Pdegrees and ending with an angle of Q degrees, with radius Radius. Arc(100,200,0,90,70); PieSlice(X,Y,P,Q,Radius); Similar to the arc();, except in that it is a pie. PieSlice(90,150,20,95,100); Bar(X1,Y1,X2,Y2); Draws a bar filled with the current colour, starting from X1, X2 to Y1, Y2. Bar(50,100,150,500); Bar3D(X1,Y1,X2,Y2, Depth,ThreeD_Top); Similar to the one above, except in that it is 3D. The last parameter indicates the 3D top of the 3D Bar. Bar3D(120,100,250, 150,50,TopOn);

Below is a really fantastic graphics program, which uses most of the graphics statements above. If you could not run the program because of a graphics error, then send me an e-mail and I will help you how to do so. But first of all, try the path of the BGI file as shown above. You can download or copy this program:

 ```Program Lesson8_Program2; {Author: Victor J. Saliba} {victorsaliba@hotmail.com} {Website: http://pascal-programming.info/} Uses Crt,Graph; Var Gd, Gm, Radius, Grow, IncP, IncQ : Integer; DecrP, DecrQ : Boolean;``` ```Begin Gd := Detect; InitGraph(Gd, Gm, ''); {Do not forget to change the dir path} {Try C:\TP\BGI} if GraphResult <> grOk then Halt(1); Randomize; SetColor(Random(15)+1); {In the following loop, 600 circles: circles with different radii are drawn. Everytime the loop is repeated, the radius increases by one, and thus the circle becomes +1 larger than the previous one.} For Radius := 1 to 600 do Begin Circle(GetMaxX Div 2, GetMaxY Div 2, Radius); Delay(1); End; ClearViewPort; SetTextJustify(230, GetMaxY Div 2); OutTextXY(230,GetMaxY Div 2,'Prepare for another one...'); Delay(1000); ClearViewPort; Grow := 0; {The ellipse loop, is similar to the one above except in that the vertical radius increases by 1} For Radius := 1 to 600 do Begin Inc(Grow); Ellipse(GetMaxX Div 2, GetMaxY Div 2, 0, 360, GetMaxX Div 2, Radius + Grow); Delay(1); End; ClearViewPort; SetTextJustify(230, GetMaxY Div 2); OutTextXY(230,GetMaxY Div 2,'Now what?'); Delay(1000); ClearViewPort; {Here's another graphics invention of mine! Similar to the first one, but using two circles positioned on both edges of the screen, continously increasing in size} For Radius := 1 to 600 do Begin Circle(GetMaxX Div 2, 0, Radius); Circle(GetMaxX Div 2, GetMaxY, Radius); Delay(2); End; Delay(1000); ClearViewPort; SetTextJustify(230, GetMaxY Div 2); OutTextXY(230,GetMaxY Div 2,'What are you lookin'' at?'); Delay(1000); ClearViewPort; Grow := 0; {Below is a simple rectangle loop, which inreases its size by 1 (increment x1,y1 and decrement x2,y2)} For Radius := 1 to 600 do Begin Inc(Grow); Rectangle(((GetMaxX Div 2) - Radius) - Grow, ((GetMaxY Div 2) - Radius)- Grow, ((GetMaxX Div 2) + Radius) + Grow, ((GetMaxY Div 2) + Radius) + Grow); Delay(2); End; ClearDevice; SetTextJustify(230, GetMaxY Div 2); OutTextXY(230,GetMaxY Div 2, 'Rotor of a helicopter thorn apart..'); Delay(2000); ClearDevice; {The demonstration below shows 4 rotating sectors, moving horizontally, and 4 other sectors in the opposite direction} IncP := 0; IncQ := 0; For Radius := 1 to 320 do Begin Inc(IncQ, 1); Inc(IncP, (IncQ Div 2)); PieSlice(GetMaxX Div 2 + IncP, GetMaxY Div 2, 0 + IncP, 2 + IncP, 240); PieSlice(GetMaxX Div 2 + IncP, GetMaxY Div 2, 180 + IncP, 182 + IncP, 240); PieSlice(GetMaxX Div 2 + IncP, GetMaxY Div 2, 88 + IncP, 90 + IncP, 240); PieSlice(GetMaxX Div 2 + IncP, GetMaxY Div 2, 268 + IncP, 270 + IncP, 240); PieSlice(GetMaxX Div 2 - IncP, GetMaxY Div 2, 45 + IncP, 47 + IncP, 240); PieSlice(GetMaxX Div 2 - IncP, GetMaxY Div 2, 135 + IncP, 137 + IncP, 240); PieSlice(GetMaxX Div 2 - IncP, GetMaxY Div 2, 225 + IncP, 227 + IncP, 240); PieSlice(GetMaxX Div 2 - IncP, GetMaxY Div 2, 315 + IncP, 317 + IncP, 240); Delay(10); ClearDevice; If IncP >= 220 then Dec(IncQ, 4); End; ClearViewPort; SetTextJustify(230, GetMaxY Div 2); OutTextXY(230,GetMaxY Div 2,'Ah, now it is repaired..'); Delay(2000); ClearDevice; {The next demonstration shows a fantastic rotor-like movement animation} {Do not be amazed by the coding below - it's very simple} {To make such animation, all you have to do is to make a sector rotating by simply increasing its degrees and clear the old one} IncP := 0; IncQ := 0; For Radius := 1 to 320 do Begin Inc(IncQ, 1); Inc(IncP, (IncQ Div 4)); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 0 + IncP, 2 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 180 + IncP, 182 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 90 + IncP, 92 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 270 + IncP, 272 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 45 + IncP, 47 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 135 + IncP, 137 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 225 + IncP, 227 + IncP, 240); PieSlice(GetMaxX Div 2, GetMaxY Div 2, 315 + IncP, 317 + IncP, 240); Delay(10); ClearDevice; End; SetTextJustify(230, GetMaxY Div 2); OutTextXY(220,GetMaxY Div 2,'The chop is on its way!'); Delay(1000); ClearDevice; Randomize; IncP := Random(GetMaxX) + 1; IncQ := 0; DecrP := False; DecrQ := False; For Radius := 1 to MaxInt do Begin If not(DecrP) then Inc(IncP,3) Else If DecrP then Dec(IncP,3); If not(DecrQ) then Inc(IncQ,3) Else If DecrQ then Dec(IncQ,3); SetColor(LightCyan); {Now FillCircle! - same radii (20)} FillEllipse(IncP,IncQ, 20, 20); Circle(IncP, IncQ, 40); PieSlice(IncP, IncQ, 0 + (IncP * 80), 6 + (IncP * 80), 100); PieSlice(IncP, IncQ, 180 + (IncP * 80), 186 + (IncP * 80), 100); PieSlice(IncP, IncQ, 90 + (IncP * 80), 96 + (IncP * 80), 100); PieSlice(IncP, IncQ, 270 + (IncP * 80), 276 + (IncP * 80), 100); If IncP > GetmaxX then DecrP := True Else If IncP < 0 then DecrP := False; If IncQ > GetmaxY then DecrQ := True Else If IncQ < 0 then DecrQ := False; Delay(10); ClearDevice; {Try to remove this :-)} If KeyPressed then Break; End; ReadKey; SetTextStyle(SansSerifFont,HorizDir,1); SetUserCharSize(2,1,5,1); OutTextXy(12,20,'Was it fun? Ehh???'); SetUserCharSize(1,1,2,1); SetColor(LightCyan); OutTextXY(35,190,'Now you can try to do it yourself.'); OutTextXY(20,240,'If you have any comments then send'); OutTextXY(180,300,'me an e-mail to'); OutTextXY(120,400,'victorsaliba@hotmail.com'); Readln; CloseGraph; End.```

Have you successfully ran the program above? How's it? There are many different animations! I used some statements which you are'nt still familiar with. But, sooner or later, you will get to know how to use them and know their function.

There are many other graphics procedures and functions, which do not draw graphic objects, but manipulate the format of the graphic objects you draw. For example, if I want to fill a circle with a colour, it's like this:

Circle(GetMaxX Div 2, GetMaxY Div 2, 60);
FillEllipse(GetMaxX Div 2, GetMaxY Div 2, 60, 60); {Note the radii}

The command 'FillEllipse' will fill the circle with the current colour. Take a look at the table below:

 Statement Description Example SetFillStyle(Pattern, Colour); Changes the style of the filling of an object. It can only be used with bar/bar3d and pieslice. It has 13 different fill styles. SetFillStyle(XHatchFill,LightCyan); OR SetFillStyle(10,3); SetUserCharSize(MultX, DivX, MultY, DivY); Display the text in a larger or smaller size. SetUserCharSize(5,1,3,1); SetTextStyle(Font, Direction, Size); Display text using the font style, orientation and size indicated as shown. SetTextStyle(TriplexFont, HorizDir,2); ClearViewPort; Clears the active screen page. ClearViewPort; GetDriverName Get the driver name being currently used. OutText('Using driver:' + GetDriverName);

It is useful to try to run the program below yourself so as to understand the meaning of several reserved words included in certain functions, such as:

SetTextStyle(SansSerifFont,VertDir,2);

OR

Bar3D(40,50,60,100,50,TopOn);

 ```Program Lesson8_Program3; Uses Graph; Var Gd, Gm: Integer; Begin Gd := Detect; InitGraph(Gd, Gm, ' '); if GraphResult <> grOk then Halt(1); SetTextStyle(TriplexFont, HorizDir, 1); SetUserCharSize(2,1,10,1); SetTextJustify(CenterText, CenterText); OutTextXY(GetMaxX Div 2,200,'Is it big enough?'); readln; ClearViewPort; SetTextStyle(SmallFont, VertDir, 5); SetTextJustify(LeftText,CenterText); OutTextXY(200,250,'VertDir (vertical) Direction. Do you understand now??'); Readln; ClearViewPort; Bar3d(150,80,450,330,50,TopOn); SetTextStyle(SansSerifFont, HorizDir, 2); SetColor(LightRed); OutTextXY(130,410,'BAR3D(150,80,350,330,50,TopOn);'); Readln; ClearViewPort; Bar3d(150,80,450,330,50,TopOff); SetColor(LightGreen); OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOff);'); Readln; ClearViewPort; OutTextXY(130,380,'SetFillStyle(BkSlashFill,7);'); SetFillStyle(BkSlashFill,7); Bar3d(150,80,450,330,50,TopOn); OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOn);'); Readln; ClearViewPort; OutTextXY(130,380,'SetFillStyle(XHatchFill,6);'); SetFillStyle(XHatchFill,6); Bar3d(150,80,450,330,50,TopOn); OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOn);'); Readln; CloseGraph; End.```

This is just the beginning of the graphics adventure. If you would like to be a guru in graphics, just keep on practicing and produce only graphical programs.

Comments are no longer accepted due to a defeated battle against an overwhelimg amounts of incoming spam! Apologies for any inconvenience.

`© Victor John Saliba 2006  | Privacy Statement | Disclaimer | Contact Us |`