Hello there !
So it's my first post

First, just a few words to present myself :
I'm a french (so please excuse me if some of my sentences sound ambiguous !) freebasic user since some years now but I really don't define myself as a programmer ! In fact, I started "coding" on a TO7 and a ZX Spectrum (by "coding", i mean copying the programs listed in the manual and writing some ultra simple stuff). Then I coded a bit on PC with QBasic, I quickly stopped and started to code with GFA Basic on my Atari Mega STE (The only thing I ever really coded with it were a pong)

So 1 or 2 years ago, after some years without coding anything, I decided to start again coding and I found an awesome language which was (and IS) freebasic !
Oh and I'm a musician too

Guitar, saxophone, drums and computer music. Don't ask me if I ever written any demo music, the answer is no :p I tried one or two times but it was catastrophic

Well ! So now, about the Gouraud filling

The relsoft's tutorial (
http://www.phatcode.net/articles.php?id=214) helped me a lot since it totally guided me through this small project. Thanks a lot to him for that ! And thanks to Freebasic forum users which helped me a lot to understand Screen buffer access, especially counting_pine (I didn't want to use Pset : even if my code is everything but optimized, I wanted to access the buffer "by myself").
a screenshot :

a Zip with code+Exe :
http://narky00.free.fr/Gouraud.rarAnd the code :
#Define Norm(a) sqr(a.x*a.x + a.y*a.y + a.z*a.z)
Const MAX_TRIANGLES_PER_OBJECT = 500
Const xRes = 640, yRes = 480
Dim shared as integer ptr ScrPtr
Screenres xRes,yRes,32,2
ScrPtr = Screenptr
Type Vector
as single x,y,z
End Type
Type ColorT
as integer r,g,b
End Type
Type VertexT
as Vector Pos3d
as Vector Pos2d
as ColorT Color
End Type
Type TriangleT
as Vector Normal
as integer idZ
as VertexT Vertex(2)
End Type
Type ObjectT
as TriangleT Triangle(MAX_TRIANGLES_PER_OBJECT)
as Vector Center
as integer nb_triangles
End Type
'' 3d Characteristics
Dim shared as single FOV = 256
Sub Sort_Object_Z(obj as ObjectT)
For i as integer = 1 to obj.nb_Triangles
obj.triangle(i).IdZ = i
if i>1 then
if obj.triangle(i).vertex(0).pos3d.z + obj.triangle(i).vertex(1).pos3d.z + obj.triangle(i).vertex(2).pos3d.z < obj.triangle(i-1).vertex(0).pos3d.z + obj.triangle(i-1).vertex(1).pos3d.z + obj.triangle(i-1).vertex(2).pos3d.z then
Swap obj.triangle(i), obj.triangle(i-1)
i=1
end if
end if
Next
End Sub
Sub Calc_Triangle_2d_ZNormal(Tri as TriangleT)
Tri.Normal.Z = (Tri.Vertex(1).pos2d.x - Tri.Vertex(0).pos2d.x) * (Tri.Vertex(0).pos2d.y - Tri.Vertex(2).pos2d.y) - (Tri.Vertex(1).pos2d.y - Tri.Vertex(0).pos2d.y) * (Tri.Vertex(0).pos2d.x - Tri.Vertex(2).pos2d.x)
End Sub
Sub Calc_Triangle_Normal(Tri as TriangleT)
dim as single ax,bx,ay,by,az,bz
ax = Tri.Vertex(1).pos3d.x - Tri.Vertex(0).pos3d.x
bx = Tri.Vertex(2).pos3d.x - Tri.Vertex(1).pos3d.x
ay = Tri.Vertex(1).pos3d.y - Tri.Vertex(0).pos3d.y
by = Tri.Vertex(2).pos3d.y - Tri.Vertex(1).pos3d.y
az = Tri.Vertex(1).pos3d.z - Tri.Vertex(0).pos3d.z
bz = Tri.Vertex(2).pos3d.z - Tri.Vertex(1).pos3d.z
Tri.Normal.x = ay * bz - az * by
Tri.Normal.y = az * bx - ax * bz
Tri.Normal.z = ax * by - ay * bx
'' Not normalized for now !! Normalize it if Code shading !
End Sub
Sub Project_Object(Obj as ObjectT)
if obj.nb_triangles = 0 then exit Sub
For i as integer = 1 to obj.nb_triangles
For j as integer = 0 to 2
if obj.Center.z + obj.Triangle(i).Vertex(j).pos3d.z = FOV then obj.Triangle(i).Vertex(j).pos3d.z+=1
obj.Triangle(i).Vertex(j).pos2d.x = xRes/2 + FOV * (obj.Center.x + obj.Triangle(i).Vertex(j).pos3d.x) / (FOV - (obj.Center.z + obj.Triangle(i).Vertex(j).pos3d.z))
obj.Triangle(i).Vertex(j).pos2d.y = yRes/2 - FOV * (obj.Center.y + obj.Triangle(i).Vertex(j).pos3d.y) / (FOV - (obj.Center.z + obj.Triangle(i).Vertex(j).pos3d.z))
Next
Next
End Sub
Sub GLine(ByVal x1 as integer,ByVal x2 as integer, y as integer,ByVal r1 as integer,ByVal g1 as integer,ByVal b1 as integer,ByVal r2 as integer,ByVal g2 as integer,ByVal b2 as integer)
dim as single dR,dG,dB
dim as single R,g,b
dim as integer itx1,itx2
dim as single sr1,sr2,sg1,sg2,sb1,sb2
if x1<x2 then
itx1 = x1
itx2 = x2
sr1 = r1
sr2 = r2
sg1 = g1
sg2 = g2
sb1 = b1
sb2 = b2
else
itx1 = x2
itx2 = x1
sr1 = r2
sr2 = r1
sg1 = g2
sg2 = g1
sb1 = b2
sb2 = b1
end if
dR = (sr2 - sr1)/(itx2 - itx1)
dG = (sg2 - sg1)/(itx2 - itx1)
dB = (sb2 - sb1)/(itx2 - itx1)
r = sr1
g = sg1
b = sb1
for i as integer = itx1 to itx2-1
if y>0 and y<yRes and i>0 and i<xRes then
ScrPtr[y*xRes+i] = rgb(r,g,b)
end if
r += dR
g += dG
b += dB
Next
End Sub
Sub Gouraud_Fill(ByVal Triangle as TriangleT)
'' Sorting Y values
if Triangle.Vertex(1).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
swap Triangle.Vertex(1).Pos2d.y,Triangle.Vertex(0).Pos2d.y
swap Triangle.Vertex(1).Pos2d.x,Triangle.Vertex(0).Pos2d.x
swap Triangle.Vertex(1).Color.r,Triangle.Vertex(0).Color.r
swap Triangle.Vertex(1).Color.g,Triangle.Vertex(0).Color.g
swap Triangle.Vertex(1).Color.b,Triangle.Vertex(0).Color.b
end if
if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
swap Triangle.Vertex(2).Pos2d.y,Triangle.Vertex(0).Pos2d.y
swap Triangle.Vertex(2).Pos2d.x,Triangle.Vertex(0).Pos2d.x
swap Triangle.Vertex(2).Color.r,Triangle.Vertex(0).Color.r
swap Triangle.Vertex(2).Color.g,Triangle.Vertex(0).Color.g
swap Triangle.Vertex(2).Color.b,Triangle.Vertex(0).Color.b
end if
if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(1).Pos2d.y then
swap Triangle.Vertex(2).Pos2d.y,Triangle.Vertex(1).Pos2d.y
swap Triangle.Vertex(2).Pos2d.x,Triangle.Vertex(1).Pos2d.x
swap Triangle.Vertex(2).Color.r,Triangle.Vertex(1).Color.r
swap Triangle.Vertex(2).Color.g,Triangle.Vertex(1).Color.g
swap Triangle.Vertex(2).Color.b,Triangle.Vertex(1).Color.b
end if
dim as integer dx1,dy1,dx2,dy2,dx3,dy3
dim as integer dr1,dg1,db1,dr2,dg2,db2,dr3,dg3,db3
dim as single Slope1,Slope2,Slope3
dim as single RSlope1, GSlope1,BSlope1
dim as single RSlope2, GSlope2,BSlope2
dim as single RSlope3, GSlope3,BSlope3
'' interpolate 0 to 1 (pos + color)
dX1 = Triangle.Vertex(1).pos2d.x - Triangle.Vertex(0).pos2d.x
dY1 = Triangle.Vertex(1).pos2d.y - Triangle.Vertex(0).pos2d.y
dr1 = Triangle.Vertex(1).color.r - Triangle.Vertex(0).color.r
dg1 = Triangle.Vertex(1).color.g - Triangle.Vertex(0).color.g
db1 = Triangle.Vertex(1).color.b - Triangle.Vertex(0).color.b
if dY1 <> 0 then
Slope1 = dX1 / dY1
RSlope1 = dR1 / dY1
GSlope1 = dG1 / dY1
BSlope1 = dB1 / dY1
else
Slope1 = 0
RSlope1 = 0
GSlope1 = 0
BSlope1 = 0
End if
'' interpolate 1 to 2
dX2 = Triangle.Vertex(2).pos2d.x - Triangle.Vertex(1).pos2d.x
dY2 = Triangle.Vertex(2).pos2d.y - Triangle.Vertex(1).pos2d.y
dr2 = Triangle.Vertex(2).color.r - Triangle.Vertex(1).color.r
dg2 = Triangle.Vertex(2).color.g - Triangle.Vertex(1).color.g
db2 = Triangle.Vertex(2).color.b - Triangle.Vertex(1).color.b
if dY2 <> 0 then
Slope2 = dX2 / dY2
RSlope2 = dR2 / dY2
GSlope2 = dG2 / dY2
BSlope2 = dB2 / dY2
else
Slope2 = 0
RSlope2 = 0
GSlope2 = 0
BSlope2 = 0
End if
'' interpolate 0 to 2
dX3 = Triangle.Vertex(0).pos2d.x - Triangle.Vertex(2).pos2d.x
dY3 = Triangle.Vertex(0).pos2d.y - Triangle.Vertex(2).pos2d.y
dr3 = Triangle.Vertex(0).color.r - Triangle.Vertex(2).color.r
dg3 = Triangle.Vertex(0).color.g - Triangle.Vertex(2).color.g
db3 = Triangle.Vertex(0).color.b - Triangle.Vertex(2).color.b
if dY3 <> 0 then
Slope3 = dX3 / dY3
RSlope3 = dR3 / dY3
GSlope3 = dG3 / dY3
BSlope3 = dB3 / dY3
else
Slope3 = 0
RSlope3 = 0
GSlope3 = 0
BSlope3 = 0
End if
'' Drawing
'' Top
dim as single CurX1=Triangle.Vertex(0).pos2d.x, CurX2=Triangle.Vertex(0).pos2d.x
dim as single CurR1=Triangle.Vertex(0).Color.r,_
CurG1=Triangle.Vertex(0).Color.g,_
CurB1=Triangle.Vertex(0).Color.b,_
CurR2=Triangle.Vertex(0).Color.r,_
CurG2=Triangle.Vertex(0).Color.g,_
CurB2=Triangle.Vertex(0).Color.b
'BufferIter = Triangle.Vertex(0).pos2d.y * xRes
For y as integer = Triangle.Vertex(0).pos2d.y to Triangle.Vertex(1).pos2d.y-1
GLine(CurX1,CurX2,y,CurR1,CurG1,CurB1,CurR2,CurG2,CurB2)
CurX1 += Slope1
CurX2 += Slope3
CurR1 += RSlope1
CurR2 += RSlope3
CurG1 += GSlope1
CurG2 += GSlope3
CurB1 += BSlope1
CurB2 += BSlope3
'BufferIter += xRes
Next
'' down
CurX1 = Triangle.Vertex(1).pos2d.x
CurR1 = Triangle.Vertex(1).color.r
Curg1 = Triangle.Vertex(1).color.g
Curb1 = Triangle.Vertex(1).color.b
For y as integer = Triangle.Vertex(1).pos2d.y to Triangle.Vertex(2).pos2d.y-1
GLine(CurX1,CurX2,y,CurR1,CurG1,CurB1,CurR2,CurG2,CurB2)
CurX1 += Slope2
CurX2 += Slope3
CurR1 += RSlope2
CurR2 += RSlope3
CurG1 += GSlope2
CurG2 += GSlope3
CurB1 += BSlope2
CurB2 += BSlope3
'BufferIter += xRes
Next
End Sub
Sub Rotate(obj as objectT,Tx as single, Ty as single, Tz as single)
dim as single tmpX,tmpY,TmpZ
For i as integer = 1 to obj.NB_triangles
For j as integer = 0 to 2
TmpY = obj.Triangle(i).Vertex(j).pos3d.y * cos(Tx) - obj.Triangle(i).Vertex(j).pos3d.z * sin(Tx)
TmpZ = obj.Triangle(i).Vertex(j).pos3d.z * cos(Tx) + obj.Triangle(i).Vertex(j).pos3d.y * sin(Tx)
obj.Triangle(i).Vertex(j).pos3d.y = TmpY
obj.Triangle(i).Vertex(j).pos3d.z = TmpZ
TmpZ = obj.Triangle(i).Vertex(j).pos3d.z * cos(Ty) - obj.Triangle(i).Vertex(j).pos3d.x * sin(Ty)
TmpX = obj.Triangle(i).Vertex(j).pos3d.x * cos(Ty) + obj.Triangle(i).Vertex(j).pos3d.z * sin(Ty)
obj.Triangle(i).Vertex(j).pos3d.x = TmpX
TmpX = obj.Triangle(i).Vertex(j).pos3d.x * cos(Tz) - obj.Triangle(i).Vertex(j).pos3d.y * sin(Tz)
TmpY = obj.Triangle(i).Vertex(j).pos3d.y * cos(Tz) + obj.Triangle(i).Vertex(j).pos3d.x * sin(Tz)
obj.Triangle(i).Vertex(j).pos3d.x = TmpX
obj.Triangle(i).Vertex(j).pos3d.y = TmpY
obj.Triangle(i).Vertex(j).pos3d.z = TmpZ
Next
Next
End sub
'' Test
Dim as objectT Pyramid
Pyramid.nb_triangles = 4
Pyramid.Center.z = 1
Pyramid.Center.y = 0
Pyramid.Center.x = 0
For i as integer = 1 to Pyramid.nb_triangles
for j as integer = 0 to 2
Read Pyramid.triangle(i).Vertex(j).pos3d.x, Pyramid.triangle(i).Vertex(j).pos3d.y,Pyramid.triangle(i).Vertex(j).pos3d.z,Pyramid.triangle(i).Vertex(j).Color.r,Pyramid.triangle(i).Vertex(j).Color.g,Pyramid.triangle(i).Vertex(j).Color.b
Pyramid.triangle(i).Vertex(j).pos3d.x *= 4
Pyramid.triangle(i).Vertex(j).pos3d.y *= 4
Pyramid.triangle(i).Vertex(j).pos3d.z *= 4
next
next
dim as single t=.02
dim as single tmpx,tmpz,tmpy
dim as integer j
Do
Screenlock : cls
Project_object Pyramid
Sort_object_Z Pyramid
For i as integer = 1 to Pyramid.nb_triangles
Calc_Triangle_Normal Pyramid.triangle(i)
if Pyramid.triangle(i).Normal.Z>0 then
Gouraud_Fill Pyramid.triangle(i)
end if
Next
Rotate(Pyramid,t/2,t/3,t/2)
screenunlock : sleep 1,1
loop until multikey(&h01)
'' triangle 1
Data 0,30,0,250,50,50
Data 20,0,-20,50,250,50
Data -20,0,-20,50,50,250
'' triangle 2
Data 0,30,0,250,50,50
Data 0,0,20,250,50,250
Data 20,0,-20,50,250,50
'' triangle 3
Data 0,30,0,250,50,50
Data -20,0,-20,50,50,250
Data 0,0,20,250,50,250
'' triangle 4
Data 20,0,-20,50,250,50
Data 0,0,20,250,50,250
Data -20,0,-20,50,50,250To finish, let me tell you that I red and saw a lot of awesome stuff here, especially ultra optimized stuff, so please excuse the fact that this code is more a proof-that-I-can-do-this than a real compo. The next steps are resolving some glitches, and then, coding a Gouraud shading routine with lights

++ !
Hezad *glad to be there*
ps : Code Updated (Not the zip though) : the pyramid was moving a bit too fast :p