# QB CULT MAGAZINEVol. 2 Iss. 2 - May 2001

## Graphics Programming, Part 2Gouraud Shaded Polys

By Sane <sane@telia.com>

Last issue you learned how to program flat-shaded polys. (yes, seriously, you did :) This time you'll learn a more fancy method for shading, namely gouraud shading. Gouraud shading has probably got it's name from some guy called A. A. Gouraud or something, I don't really know, but who cares anyways? :)

Gouraud shading is based on interpolating color values for a whole poly, based on 3 colors (one for each corner), to simulate light, for example. Polys drawn using gouraud shading will look similar to this: Gouraud shading is done pretty much like flat-shading, but you also need to interpolate the color values vertically, and then draw the polys using a customized horizontal line drawing routine, which interpolates the line between two colors. The steps are shown in this picture: First we'll make the line drawing routine, since we won't see if our gouraud poly routine really works unless we can draw the polys.

The line color values are calculated pretty much the same way we calculated the x values for the poly in the previous article, with the difference that we use the color and x distance for calculating the medium, instead of using the x and y values. The formula becomes cm = (c2 - c1) / (x2 - x1), where cm is the medium color distance, c1 is color 1, and you probably understand the rest.

Then the line drawing is done using good(?) old(!) PSET :)

Here's a code example:

```'Made by Sane at the 22nd of May 2001, for QBCM'
SUB gLINE (x1, x2, y, c1, c2)
'Sorting x and color values
IF x1 > x2 THEN SWAP x1, x2: SWAP c1, c2

'Calculating of the medium distance between colors
cm = 0
c = 0
IF c2 - c1 <> 0 AND x2 - x1 <> 0 THEN cm = (c2 - c1) / (x2 - x1)

'Drawing
FOR x = x1 TO x2
PSET (x, y), c + c1
c = c + cm
NEXT x
END SUB
```

And now to the poly routine. We'll base the poly routine on the old, flat-shaded one, with the changes needed for gouraud shading.

The changes we'll make are:

• Adding an array for storing the y color values for the poly, similar to the one for slopes
• Sorting colors at the same time we sort the points, to make the colors stay at the points they're supposed for
• Calculating the color blend between points, while also calculating the slopes
• Altering the drawing part slightly
```'Made by Sane at the 22nd of May 2001, for QBCM
SUB gpoly (xx1, yy1, xx2, yy2, xx3, yy3, cc1, cc2, cc3)
'Declare an array for storing slopes
DIM poly(199, 1)
'Declare an array for storing color values
DIM colr(199, 1)
'Point and color sorting
IF yy1 < yy2 AND yy1 < yy3 THEN x1 = xx1: y1 = yy1: c1 = cc1
IF yy2 < yy1 AND yy2 < yy3 THEN x1 = xx2: y1 = yy2: c1 = cc2
IF yy3 < yy1 AND yy3 < yy2 THEN x1 = xx3: y1 = yy3: c1 = cc3

IF yy1 > yy2 AND yy1 > yy3 THEN x3 = xx1: y3 = yy1: c2 = cc1
IF yy2 > yy1 AND yy2 > yy3 THEN x3 = xx2: y3 = yy2: c2 = cc2
IF yy3 > yy1 AND yy3 > yy2 THEN x3 = xx3: y3 = yy3: c2 = cc3

IF yy1 <> y1 AND yy1 <> y3 THEN x2 = xx1: y2 = yy1: c3 = cc1
IF yy2 <> y1 AND yy2 <> y3 THEN x2 = xx2: y2 = yy2: c3 = cc2
IF yy3 <> y1 AND yy3 <> y3 THEN x2 = xx3: y2 = yy3: c3 = cc3

'Calculating of the slope and color blend from point 1 to point 2
m = 0
x = 0
c = 0
cm = 0
IF x1 + x2 <> 0 AND y1 + y2 <> 0 THEN m = (x1 - x2) / (y1 - y2)
IF c1 + c2 <> 0 AND y1 + y2 <> 0 THEN cm = (c1 - c2) / (y1 - y2)
FOR y = y1 TO y2
poly(y, 0) = x + x1
colr(y, 0) = c + c1
x = x + m
c = c + cm
NEXT y

'Calculating of the slope and color blend from point 2 to point 3
m = 0
x = 0
c = 0
cm = 0
IF x2 + x3 <> 0 AND y2 + y3 <> 0 THEN m = (x2 - x3) / (y2 - y3)
IF c2 + c3 <> 0 AND y2 + y3 <> 0 THEN cm = (c2 - c3) / (y2 - y3)
FOR y = y2 TO y3
poly(y, 0) = x + x2
colr(y, 0) = c + c2
x = x + m
c = c + cm
NEXT y

'Calculating of the slope and color blend from point 1 to point 3
m = 0
x = 0
c = 0
cm = 0
IF x1 + x3 <> 0 AND y1 + y3 <> 0 THEN m = (x1 - x3) / (y1 - y3)
IF c1 + c3 <> 0 AND y1 + y3 <> 0 THEN cm = (c1 - c3) / (y1 - y3)
FOR y = y1 TO y3
poly(y, 1) = x + x1
colr(y, 1) = c + c1
x = x + m
c = c + cm
NEXT y

'The easiest part, drawing
FOR y = y1 TO y3
gLINE poly(y, 0), poly(y, 1), y, colr(y, 0), colr(y, 1)
NEXT y
END SUB
```

And some code for testing it:

```'Made by Sane at the 22nd of May 2001, for QBCM
SCREEN 13

'Changing the palette to greyscale
FOR i = 0 TO 255
OUT &H3C8, i
OUT &H3C9, i \ 4
OUT &H3C9, i \ 4
OUT &H3C9, i \ 4
NEXT i

'Setting color for PPS (Poly Per Second) rate text
COLOR 255

oldtimer! = TIMER
DO UNTIL INKEY\$ = CHR\$(27)
x1 = INT(RND * 320)
x2 = INT(RND * 320)
x3 = INT(RND * 320)
y1 = INT(RND * 200)
y2 = INT(RND * 200)
y3 = INT(RND * 200)
gpoly x1, y1, x2, y2, x3, y3, INT(RND * 255), INT(RND * 255), INT(RND * 255)
polynum = polynum + 1
IF TIMER > oldtimer! + 1 THEN LOCATE 1, 1: PRINT polynum: oldtimer! = TIMER: polynum = 0
LOOP
```

And just as last time, there's a file with the source available for you lazy guys who are too lazy to type it into QB yourselves :) This time it's named GPOLY.BAS

And a screenshot: Note that there's a bug in it, which makes some of the polys have small gaps, I haven't managed to figure out why yet, as I wrote the code about 5 minutes ago, and I really need to get QBCM released this afternoon :) I might give you a better version in the next article, in case I've gotten rid of the bug by then...

This is mighty slow, as you might have noticed... Even though I've now got a Pentium 2 300 mHz (managed to fix it since last issue, when this comp was broken), I only get about 18 PPS(Polys Per Second), which really sucks...

Thus, the next parts subject will be: