• Welcome to Dark Bit Factory & Gravity.
 

WIP 3D Engine (Update : v0.07 screenie preview) [v0.06]

Started by Hezad, August 21, 2008

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Hezad

#20
Well erm.. So after a big verification, my Z-axis IS inversed. In fact, he's in the other direction I thought :p And Vertices must be declared Counter-clockwise ! uhuh So now It's way easier to understand and visualize where my vertices are.

But !

I suppressed my cube and started a new one to make sure there are no errors. Well the cube looks better but there is still a bug : On some faces (the majority in fact), we can see the diagonal line when 2 triangles meet on a face : There should be a gradient but the demarcation is pretty visible (see screenshot) ???

I guess there is a problem in the Vertex Normal Calc but now i need to find it :p If you have any idea of what can cause that ...



edit : Well I found the origin of the problem : If I calc my normals on each loop instead of rotating the precalculated ones, It works perfectly ! So the problem comes from the way I rotate my normals !

Re-edit : O_o in fact, I just have to run the precalc_normals sub twice, and then the rotation is ok.
That's really weird :p But for now it works :D



Re-Re-edit :
aaand, I fouuund it !! Rah what a dumb I am :whack: A simple inattention bug :p Ok so now it works, without any trick behind ^^

Next step : Gouraud shading on texture mapped polys
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Hezad

#21
Update !

Now Texture mapped objects support Gouraud shading  :updance:


Code (Needs the texture in the attached Rar file) :



''  =======================---. 3D Stuff .---=======================
''
''      Gouraud Shading + Z-Buffer rendering
''
''                      Code : Hezad  [   Hezad0 )at( Gmail.com    ]
''
''
''  Thanks to Relsoft for his awesome tutorial :
''                 [  http://www.phatcode.net/articles.php?id=214  ]
''
''
''  ================================================================


#Define Norm(a) sqr(a.x*a.x + a.y*a.y + a.z*a.z)

Const MAX_TRIANGLES_PER_OBJECT = 500
Const MAX_OBJECTS = 10
Const xRes = 640, yRes = 480

Const SCREEN_MEM = xRes * yRes

Const BGND_COLOR = rgb(50,50,70)

Const FOV = 512, ZOOM = 512

Const MAX_Z = 1000

Const PI = 3.1415926535897932384626
Const PIx2 = 2*PI

Const ToRad = PIx2/360
Const ToDeg = 360/PIx2



Dim shared as integer ptr ScrPtr
ReDim shared as integer ZBuffer(SCREEN_MEM)

Screenres xRes,yRes,32,2

ScrPtr = Screenptr

Dim shared as single FPS_t,CurFPS,FPS_counter

Type Vector
    as single x,y,z
End Type

Type ColorT
    as integer r,g,b
End Type

Type TextureT
   
    as vector Size

    as integer ptr GFX
   
End Type

Sub Set_Texture_Size(Text as TextureT, x as integer, y as integer)
   
    If Text.GFX <> 0 then deallocate Text.GFX
   
    Text.Size.x = x
    Text.Size.y = y-1
   
    Text.GFX = Callocate(x*y,sizeof(integer))
   
End Sub

Type VertexT
   
    as Vector Pos3d
   
    as Vector Gouraud_Normal
   
    as Vector Pos2d
   
    as ColorT Color
   
    as ColorT OriginalColor
   
    as single U,V
   
End Type

Type TriangleT
   
    as Vector Normal
   
    as integer idZ
   
    as VertexT Vertex(2)
   
    as Vector Parent_Center
   
End Type

Type ObjectT
   
    as TriangleT Triangle(MAX_TRIANGLES_PER_OBJECT)
   
    as Vector Center
   
    as integer nb_triangles
   
End Type

Type LightT
   
    Pos3d as Vector
   
    Intensity as single
   
End Type

Type CameraT
   
    Pos as Vector
   
    Angle as Vector
   
End Type


Dim shared as CameraT Camera

Sub Set_Camera(x as integer, y as integer, z as integer)
   
    Camera.Pos.x = x
    Camera.Pos.y = y
    Camera.Pos.z = z
   
End Sub

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_Normal(Tri as TriangleT)
   
    dim as single ax,bx,ay,by,az,bz,NNorm
   
    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
   
    '' Normalize
    NNorm = 1/Norm(Tri.Normal)
   
    Tri.Normal.x *= NNorm
    Tri.Normal.y *= NNorm
    Tri.Normal.z *= NNorm
   
End Sub

#Define SamePnt(a,b) iif ((a.pos3d.x = b.pos3d.x) and (a.pos3d.y = b.pos3d.y) and (a.pos3d.z = b.pos3d.z),1,0)

Sub PreCalc_Object_Normals(obj as ObjectT)
   
    dim as single tmpXNorm,TmpYNorm,TmpZNorm
   
    For k as integer = 1 to obj.nb_triangles
        '' face normal
        Calc_Triangle_Normal(obj.Triangle(k))
   
    Next
   
    for k as integer = 1 to obj.nb_triangles
       
        '' "Vertex normals"
        for i as integer = 0 to 2
            TmpXNorm = 0
            TmpYNorm = 0
            TmpZNorm = 0
           
            for j as integer = 1 to obj.nb_triangles
                if SamePnt(obj.triangle(k).Vertex(i),obj.triangle(j).Vertex(0)) or _
                    SamePnt(obj.triangle(k).Vertex(i),obj.triangle(j).Vertex(1)) or _
                    SamePnt(obj.triangle(k).Vertex(i),obj.triangle(j).Vertex(2)) then
                   
                    TmpXNorm += obj.triangle(j).Normal.x
                    TmpYNorm += obj.triangle(j).Normal.y
                    TmpZNorm += obj.triangle(j).Normal.z
                   
                end if
            next
               
            dim as single _Normm = 1/sqr(TmpXNorm*TmpXNorm+TmpYNorm*TmpYNorm+TmpZNorm*TmpZNorm)
           
            TmpXNorm *= _Normm
            TmpYNorm *= _Normm
            TmpZNorm *= _Normm
           
            obj.triangle(k).Vertex(i).Gouraud_Normal.x = TmpXNorm
            obj.triangle(k).Vertex(i).Gouraud_Normal.y = TmpyNorm
            obj.triangle(k).Vertex(i).Gouraud_Normal.z = TmpzNorm
           
        next
       
    next
   
End Sub

Function SetLight(x as single,y as single, z as single,intens as single) as LightT
   
    Dim as LightT Tmp
   
    Tmp.pos3d.x = x
    Tmp.pos3d.y = y
    Tmp.pos3d.z = z
   
    Tmp.Intensity = intens
   
    Return Tmp
   
End Function

Declare Sub Rotate(obj as objectT,Tx as single, Ty as single, Tz as single)


'' Projection ============================

Sub Project_Object(Obj as ObjectT)
   
    dim as single aX,aY,aZ
   
    if obj.nb_triangles = 0 then exit Sub
   
    For i as integer = 1 to obj.nb_triangles
       
        obj.Triangle(i).Parent_Center = obj.Center
       
        For j as integer = 0 to 2
           
            if obj.Triangle(i).Vertex(j).pos3d.z = Camera.pos.z - obj.Center.z + FOV then obj.Triangle(i).Vertex(j).pos3d.z+=.0001
           
            obj.Triangle(i).Vertex(j).pos2d.x = xRes/2 + (FOV * (-Camera.pos.x + obj.Center.x + obj.Triangle(i).Vertex(j).pos3d.x)) / (ZOOM - (Camera.pos.z + obj.Center.z + obj.Triangle(i).Vertex(j).pos3d.z))
            obj.Triangle(i).Vertex(j).pos2d.y = yRes/2 - (FOV * (-Camera.pos.y + obj.Center.y + obj.Triangle(i).Vertex(j).pos3d.y)) / (ZOOM - (Camera.pos.z + 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,ByVal z1 as integer,ByVal z2 as integer)
   
    dim as single dR,dG,dB, dZ
    dim as single R,g,b
   
    dim as integer itx1,itx2,zz1,zz2
    Dim as single CurZ,xDiv
    dim as single sr1,sr2,sg1,sg2,sb1,sb2
   
    if x1<x2 then
        zz1 = z1
        zz2 = z2
       
        itx1 = x1
        itx2 = x2
        sr1 = r1
        sr2 = r2
        sg1 = g1
        sg2 = g2
        sb1 = b1
        sb2 = b2
    else
        zz1 = z2
        zz2 = z1
       
        itx1 = x2
        itx2 = x1
        sr1 = r2
        sr2 = r1
        sg1 = g2
        sg2 = g1
        sb1 = b2
        sb2 = b1
    end if
   
    xDiv = 1/(itx2 - itx1)
   
    dR = xDiv * (sr2 - sr1)
    dG = xDiv * (sg2 - sg1)
    dB = xDiv * (sb2 - sb1)
   
    dZ = xDiv * (zz2 - zz1)
   
    r = sr1
    g = sg1
    b = sb1
   
    CurZ = zz1
   
    dim as integer it
   
    for i as integer = itx1 to itx2-1

        if y>0 and y<yRes and i>0 and i<xRes then
           
            it = y*xRes + i
           
            If (FOV - (-Camera.pos.z + CurZ))>0 then
               
                If Curz > ZBuffer(it) then
                   
                    ZBuffer(it) = CurZ
                   
                    ScrPtr[it] = rgb(r,g,b)
                   
                    '' UnComment to show the ZBuffer Gfx :D
                    'dim as integer zBufferCol = 255*cast(single,(abs(ZBuffer(it))/MAX_Z))
                    'ScrPtr[it] = rgb(zBufferCol,zBufferCol,zBufferCol)
                   
                End if
           
            end if
       
        end if
       
        curZ += dZ
       
        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),Triangle.Vertex(0)
    end if
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(0)
    end if
   
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(1).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(1)
    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, dYDiv
    dim as single RSlope1, GSlope1,BSlope1
    dim as single RSlope2, GSlope2,BSlope2
    dim as single RSlope3, GSlope3,BSlope3
   
    Dim as integer dz1,dz2,dz3
    Dim as single zSlope1,zSlope2,zSlope3
   
    '' interpolate 0 to 1 (pos + color)
   
    dZ1 = Triangle.Vertex(1).pos3d.z - Triangle.Vertex(0).pos3d.z
   
    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
       
        dYDiv = 1/dY1
       
        zSlope1 = dZ1 * dYDiv
       
        Slope1 = dX1 * dYDiv
       
        RSlope1 = dR1 * dYDiv
        GSlope1 = dG1 * dYDiv
        BSlope1 = dB1 * dYDiv
       
    else
       
        zSlope1 = 0
       
        Slope1 = 0
       
        RSlope1 = 0
        GSlope1 = 0
        BSlope1 = 0
       
    End if
   
   
    '' interpolate 1 to 2
   
    dZ2 = Triangle.Vertex(2).pos3d.z - Triangle.Vertex(1).pos3d.z
   
    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
       
        dYDiv = 1/dY2
       
        zSlope2 = dZ2 * dYDiv
       
        Slope2 = dX2 * dYDiv
       
        RSlope2 = dR2 * dYDiv
        GSlope2 = dG2 * dYDiv
        BSlope2 = dB2 * dYDiv
       
    else
       
        zSlope2 = 0
       
        Slope2 = 0
       
        RSlope2 = 0
        GSlope2 = 0
        BSlope2 = 0
       
    End if
   
   
    '' interpolate 0 to 2
   
    dZ3 = Triangle.Vertex(0).pos3d.z - Triangle.Vertex(2).pos3d.z
   
    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
       
        dYDiv = 1/dY3
       
        zSlope3 = dZ3 * dYDiv
       
        Slope3 = dX3 * dYDiv
       
        RSlope3 = dR3 * dYDiv
        GSlope3 = dG3 * dYDiv
        BSlope3 = dB3 * dYDiv
       
    else
       
        zSlope3 = 0
       
        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
   
    dim as single CurZ1=Triangle.Vertex(0).pos3d.z, CurZ2=Triangle.Vertex(0).pos3d.z
   
    CurZ1 += Triangle.Parent_Center.z
    CurZ2 += Triangle.Parent_Center.z
   
    '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, CurZ1, CurZ2)
       
        CurZ1 += zSlope1
        CurZ2 += zSlope3
       
        CurX1 += Slope1
        CurX2 += Slope3
       
        CurR1 += RSlope1
        CurR2 += RSlope3
        CurG1 += GSlope1
        CurG2 += GSlope3
        CurB1 += BSlope1
        CurB2 += BSlope3
       
        'BufferIter += xRes
       
    Next
   
    '' down
   
    CurZ1 = Triangle.Vertex(1).pos3d.z+Triangle.Parent_Center.z
   
    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, CurZ1, CurZ2)
       
        CurZ1 += zSlope2
        CurZ2 += zSlope3
       
        CurX1 += Slope2
        CurX2 += Slope3
       
        CurR1 += RSlope2
        CurR2 += RSlope3
        CurG1 += GSlope2
        CurG2 += GSlope3
        CurB1 += BSlope2
        CurB2 += BSlope3
       
    Next
   
End Sub
       
Sub Calc_Gouraud_Shader(obj_ as objectT,L_ as LightT)
   
    Dim as single Dot1,Dot2,Dot3,NL
   
    Dim as objectT obj = obj_
    Dim as LightT L = L_
   
   
    '' normalizing Light vector
    NL = 1/Norm(L.pos3d)
   
    L.pos3d.x *= NL
    L.pos3d.y *= NL
    L.pos3d.z *= NL
   
    '' dot products
   
    For k as integer = 1 to obj.nb_triangles
       
        Dot1 = (obj.triangle(k).Vertex(0).Gouraud_Normal.x * L.pos3d.x) + _
               (obj.triangle(k).Vertex(0).Gouraud_Normal.y * L.pos3d.y) + _
               (obj.triangle(k).Vertex(0).Gouraud_Normal.z * L.pos3d.z)
        if Dot1<0 then Dot1 = 0
        if Dot1>1 then Dot1 = 1
       
        Dot2 = (obj.triangle(k).Vertex(1).Gouraud_Normal.x * L.pos3d.x) + _
               (obj.triangle(k).Vertex(1).Gouraud_Normal.y * L.pos3d.y) + _
               (obj.triangle(k).Vertex(1).Gouraud_Normal.z * L.pos3d.z)
        if Dot2<0 then Dot2 = 0
        if Dot2>1 then Dot2 = 1
       
        Dot3 = (obj.triangle(k).Vertex(2).Gouraud_Normal.x * L.pos3d.x) + _
               (obj.triangle(k).Vertex(2).Gouraud_Normal.y * L.pos3d.y) + _
               (obj.triangle(k).Vertex(2).Gouraud_Normal.z * L.pos3d.z)
        if Dot3<0 then Dot3 = 0
        if Dot3>1 then Dot3 = 1
       
        '' apply new color
        obj_.triangle(k).Vertex(0).Color.r = obj_.triangle(k).Vertex(0).OriginalColor.r*L.Intensity*Dot1
        obj_.triangle(k).Vertex(0).Color.g = obj_.triangle(k).Vertex(0).OriginalColor.g*L.Intensity*Dot1
        obj_.triangle(k).Vertex(0).Color.b = obj_.triangle(k).Vertex(0).OriginalColor.b*L.Intensity*Dot1
       
        obj_.triangle(k).Vertex(1).Color.r = obj_.triangle(k).Vertex(1).OriginalColor.r*L.Intensity*Dot2
        obj_.triangle(k).Vertex(1).Color.g = obj_.triangle(k).Vertex(1).OriginalColor.g*L.Intensity*Dot2
        obj_.triangle(k).Vertex(1).Color.b = obj_.triangle(k).Vertex(1).OriginalColor.b*L.Intensity*Dot2
       
        obj_.triangle(k).Vertex(2).Color.r = obj_.triangle(k).Vertex(2).OriginalColor.r*L.Intensity*Dot3
        obj_.triangle(k).Vertex(2).Color.g = obj_.triangle(k).Vertex(2).OriginalColor.g*L.Intensity*Dot3
        obj_.triangle(k).Vertex(2).Color.b = obj_.triangle(k).Vertex(2).OriginalColor.b*L.Intensity*Dot3
    next
   
   
   
End sub


'' texturing
Sub TLine(ByVal x1 as integer,ByVal x2 as integer, y as integer,ByVal U1 as single,ByVal V1 as single,ByVal U2 as single,ByVal V2 as single,ByVal z1 as integer,ByVal z2 as integer,byval Texture as TextureT)
   
    dim as single dU,dV,dZ,U,V
    dim as single Uu1,Vv1,Uu2,Vv2
   
    dim as integer itx1,itx2,zz1,zz2
    Dim as single CurZ,xDiv
   
    if x1<x2 then
        zz1 = z1
        zz2 = z2
       
        itx1 = x1
        itx2 = x2
       
        Uu1 = u1
        Uu2 = u2
        Vv1 = v1
        Vv2 = v2
    else
        zz1 = z2
        zz2 = z1
       
        itx1 = x2
        itx2 = x1
       
        Uu1 = u2
        Uu2 = u1
        Vv1 = v2
        Vv2 = v1
    end if
   
    Uu1 *= Texture.Size.x
    Uu2 *= Texture.Size.x
    Vv1 *= Texture.Size.y
    Vv2 *= Texture.Size.y
   
    xDiv = 1/(itx2 - itx1)
   
    dZ = xDiv * (zz2 - zz1)
   
    dU = xDiv * (Uu2 - Uu1)
    dV = xDiv * (Vv2 - Vv1)
   
    CurZ = zz1
   
    U = Uu1
    V = Vv1
   
    dim as integer it
   
    for i as integer = itx1 to itx2-1

        if y>0 and y<yRes and i>0 and i<xRes then
           
            it = y*xRes + i
           
            If (FOV - (-Camera.pos.z + CurZ))>0 then
               
                If Curz > ZBuffer(it) then
                   
                    ZBuffer(it) = CurZ
                   
                    ScrPtr[it] = Texture.GFX[int(U)+Texture.Size.x*int(V)]
                                       
                End if
           
            end if
       
        end if
       
        U += dU
        V += dV
       
        curZ += dZ
       
    Next
   
End Sub



Sub Texture_Map(ByVal Triangle as TriangleT, _
                ByVal Texture as TextureT)      '' UV's saved in the Triangle.Vertex Type
   
   
    '' Sorting Y values
    if Triangle.Vertex(1).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
        swap Triangle.Vertex(1),Triangle.Vertex(0)
    end if
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(0)
    end if
   
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(1).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(1)
    end if
   
    dim as integer dx1,dy1,dx2,dy2,dx3,dy3
    dim as single Slope1,Slope2,Slope3, dYDiv
   
    dim as single dU1,dU2,dU3,dV1,dV2,dV3
    dim as single USlope1,USlope2,USlope3
    dim as single VSlope1,VSlope2,VSlope3
   
    Dim as integer dz1,dz2,dz3
    Dim as single zSlope1,zSlope2,zSlope3
   
    '' interpolate 0 to 1 (pos + color)
   
    dZ1 = Triangle.Vertex(1).pos3d.z - Triangle.Vertex(0).pos3d.z
   
    dX1 = Triangle.Vertex(1).pos2d.x - Triangle.Vertex(0).pos2d.x
    dY1 = Triangle.Vertex(1).pos2d.y - Triangle.Vertex(0).pos2d.y
   
    dU1 = Triangle.Vertex(1).U - Triangle.Vertex(0).U
    dV1 = Triangle.Vertex(1).V - Triangle.Vertex(0).V
   
    if dY1 <> 0 then
       
        dYDiv = 1/dY1
       
        zSlope1 = dZ1 * dYDiv
       
        Slope1 = dX1 * dYDiv
       
        USlope1 = dU1 * dYDiv
        VSlope1 = dV1 * dYDiv
       
    else
       
        zSlope1 = 0
       
        Slope1 = 0
       
        USlope1 = 0
        VSlope1 = 0
       
    End if
   
   
    '' interpolate 1 to 2
   
    dZ2 = Triangle.Vertex(2).pos3d.z - Triangle.Vertex(1).pos3d.z
   
    dX2 = Triangle.Vertex(2).pos2d.x - Triangle.Vertex(1).pos2d.x
    dY2 = Triangle.Vertex(2).pos2d.y - Triangle.Vertex(1).pos2d.y
   
    dU2 = Triangle.Vertex(2).U - Triangle.Vertex(1).U
    dV2 = Triangle.Vertex(2).V - Triangle.Vertex(1).V
   
    if dY2 <> 0 then
       
        dYDiv = 1/dY2
       
        zSlope2 = dZ2 * dYDiv
       
        Slope2 = dX2 * dYDiv
       
        USlope2 = dU2 * dYDiv
        VSlope2 = dV2 * dYDiv
       
    else
       
        zSlope2 = 0
       
        Slope2 = 0
       
        USlope2 = 0
        VSlope2 = 0
       
    End if
   
   
    '' interpolate 0 to 2
   
    dZ3 = Triangle.Vertex(0).pos3d.z - Triangle.Vertex(2).pos3d.z
   
    dX3 = Triangle.Vertex(0).pos2d.x - Triangle.Vertex(2).pos2d.x
    dY3 = Triangle.Vertex(0).pos2d.y - Triangle.Vertex(2).pos2d.y
   
    dU3 = Triangle.Vertex(0).U - Triangle.Vertex(2).U
    dV3 = Triangle.Vertex(0).V - Triangle.Vertex(2).V
   
    if dY3 <> 0 then
       
        dYDiv = 1/dY3
       
        zSlope3 = dZ3 * dYDiv
       
        Slope3 = dX3 * dYDiv
       
        USlope3 = dU3 * dYDiv
        VSlope3 = dV3 * dYDiv
       
    else
       
        zSlope3 = 0
       
        Slope3 = 0
       
        USlope3 = 0
        VSlope3 = 0
       
    End if
   
   
    '' Drawing
   
    '' Top
    dim as single CurX1=Triangle.Vertex(0).pos2d.x, CurX2=Triangle.Vertex(0).pos2d.x
    dim as single CurU1=Triangle.Vertex(0).U, CurU2=Triangle.Vertex(0).U,_
                  CurV1=Triangle.Vertex(0).V, CurV2=Triangle.Vertex(0).V
   
    dim as single CurZ1=Triangle.Vertex(0).pos3d.z, CurZ2=Triangle.Vertex(0).pos3d.z
   
    CurZ1 += Triangle.Parent_Center.z
    CurZ2 += Triangle.Parent_Center.z
   
    'BufferIter = Triangle.Vertex(0).pos2d.y * xRes
   
    For y as integer = Triangle.Vertex(0).pos2d.y to Triangle.Vertex(1).pos2d.y-1
       
        TLine(CurX1,CurX2,y,CurU1,CurV1,CurU2,CurV2, CurZ1, CurZ2, Texture)
       
        CurZ1 += zSlope1
        CurZ2 += zSlope3
       
        CurU1 += USlope1
        CurU2 += USlope3
        CurV1 += VSlope1
        CurV2 += VSlope3
       
        CurX1 += Slope1
        CurX2 += Slope3
       
        'BufferIter += xRes
       
    Next
   
    '' down
   
    CurZ1 = Triangle.Vertex(1).pos3d.z+Triangle.Parent_Center.z
   
    CurU1 = Triangle.Vertex(1).U
    CurV1 = Triangle.Vertex(1).V
   
    CurX1 = Triangle.Vertex(1).pos2d.x
   
    For y as integer = Triangle.Vertex(1).pos2d.y to Triangle.Vertex(2).pos2d.y-1
       
        TLine(CurX1,CurX2,y,CurU1,CurV1,CurU2,CurV2, CurZ1, CurZ2, Texture)
       
        CurZ1 += zSlope2
        CurZ2 += zSlope3
       
        CurX1 += Slope2
        CurX2 += Slope3
       
        CurU1 += USlope2
        CurU2 += USlope3
        CurV1 += VSlope2
        CurV2 += VSlope3
       
    Next
   
End Sub


'' Texture Mapping + Gouraud shader
'' texturing
Sub TSLine(ByVal x1 as integer,ByVal x2 as integer, y as integer,ByVal U1 as single,ByVal V1 as single,ByVal U2 as single,ByVal V2 as single,ByVal z1 as integer,ByVal z2 as integer,byval Texture as TextureT, r1 as integer,r2 as integer,g1 as integer,g2 as integer,b1 as integer,b2 as integer)
   
    dim as single dR,dG,dB
    dim as single R,g,b
   
    dim as single sr1,sr2,sg1,sg2,sb1,sb2
   
    dim as single dU,dV,dZ,U,V
    dim as single Uu1,Vv1,Uu2,Vv2
   
    dim as integer itx1,itx2,zz1,zz2
    Dim as single CurZ,xDiv
   
    if x1<x2 then
        zz1 = z1
        zz2 = z2
       
        itx1 = x1
        itx2 = x2
       
        Uu1 = u1
        Uu2 = u2
        Vv1 = v1
        Vv2 = v2
       
        sr1 = r1
        sr2 = r2
        sg1 = g1
        sg2 = g2
        sb1 = b1
        sb2 = b2
    else
        zz1 = z2
        zz2 = z1
       
        itx1 = x2
        itx2 = x1
       
        Uu1 = u2
        Uu2 = u1
        Vv1 = v2
        Vv2 = v1
       
        sr1 = r2
        sr2 = r1
        sg1 = g2
        sg2 = g1
        sb1 = b2
        sb2 = b1
    end if
   
    Uu1 *= Texture.Size.x
    Uu2 *= Texture.Size.x
    Vv1 *= Texture.Size.y
    Vv2 *= Texture.Size.y
   
    xDiv = 1/(itx2 - itx1)
   
    dR = xDiv * (sr2 - sr1)
    dG = xDiv * (sg2 - sg1)
    dB = xDiv * (sb2 - sb1)
   
    dZ = xDiv * (zz2 - zz1)
   
    dU = xDiv * (Uu2 - Uu1)
    dV = xDiv * (Vv2 - Vv1)
   
    CurZ = zz1
   
    U = Uu1
    V = Vv1
   
    r = sr1
    g = sg1
    b = sb1
   
    dim as integer it
    Dim as integer CurTex,Cr,Cg,Cb
   
    for i as integer = itx1 to itx2-1

        if y>0 and y<yRes and i>0 and i<xRes then
           
            it = y*xRes + i
           
            If (FOV - (-Camera.pos.z + CurZ))>0 then
               
                If Curz > ZBuffer(it) then
                   
                    ZBuffer(it) = CurZ
                   
                    CurTex = Texture.GFX[int(U)+Texture.Size.x*int(V)]
                   
                    dim as single _255 = 1/255
                   
                    Cb = CurTex and 255
                    Cg = (CurTex shr 8) and 255
                    Cr = (CurTex shr 16) and 255
                   
                    ScrPtr[it] = rgb(r*Cr*_255,g*Cg*_255,b*Cb*_255)
                                       
                End if
           
            end if
       
        end if
       
        U += dU
        V += dV
       
        r += dR
        g += dG
        b += dB
       
        curZ += dZ
       
    Next
   
End Sub

Sub Texture_Map_Shaded(ByVal Triangle as TriangleT, _
                       ByVal Texture as TextureT)      '' UV's saved in the Triangle.Vertex Type
   
   
    '' Sorting Y values
    if Triangle.Vertex(1).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
        swap Triangle.Vertex(1),Triangle.Vertex(0)
    end if
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(0).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(0)
    end if
   
    if Triangle.Vertex(2).Pos2d.y < Triangle.Vertex(1).Pos2d.y then
        swap Triangle.Vertex(2),Triangle.Vertex(1)
    end if
   
    dim as integer dx1,dy1,dx2,dy2,dx3,dy3
    dim as single Slope1,Slope2,Slope3, dYDiv
   
    dim as single dU1,dU2,dU3,dV1,dV2,dV3
    dim as single USlope1,USlope2,USlope3
    dim as single VSlope1,VSlope2,VSlope3
   
    Dim as integer dz1,dz2,dz3
    Dim as single zSlope1,zSlope2,zSlope3
   
    dim as integer dr1,dg1,db1,dr2,dg2,db2,dr3,dg3,db3
    dim as single RSlope1, GSlope1,BSlope1
    dim as single RSlope2, GSlope2,BSlope2
    dim as single RSlope3, GSlope3,BSlope3
   
    '' interpolate 0 to 1 (pos + color)
   
    dZ1 = Triangle.Vertex(1).pos3d.z - Triangle.Vertex(0).pos3d.z
   
    dX1 = Triangle.Vertex(1).pos2d.x - Triangle.Vertex(0).pos2d.x
    dY1 = Triangle.Vertex(1).pos2d.y - Triangle.Vertex(0).pos2d.y
   
    dU1 = Triangle.Vertex(1).U - Triangle.Vertex(0).U
    dV1 = Triangle.Vertex(1).V - Triangle.Vertex(0).V
   
    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
       
        dYDiv = 1/dY1
       
        zSlope1 = dZ1 * dYDiv
       
        Slope1 = dX1 * dYDiv
       
        USlope1 = dU1 * dYDiv
        VSlope1 = dV1 * dYDiv
       
        RSlope1 = dR1 * dYDiv
        GSlope1 = dG1 * dYDiv
        BSlope1 = dB1 * dYDiv
       
    else
       
        zSlope1 = 0
       
        Slope1 = 0
       
        USlope1 = 0
        VSlope1 = 0
       
        RSlope1 = 0
        GSlope1 = 0
        BSlope1 = 0
    End if
   
   
    '' interpolate 1 to 2
   
    dZ2 = Triangle.Vertex(2).pos3d.z - Triangle.Vertex(1).pos3d.z
   
    dX2 = Triangle.Vertex(2).pos2d.x - Triangle.Vertex(1).pos2d.x
    dY2 = Triangle.Vertex(2).pos2d.y - Triangle.Vertex(1).pos2d.y
   
    dU2 = Triangle.Vertex(2).U - Triangle.Vertex(1).U
    dV2 = Triangle.Vertex(2).V - Triangle.Vertex(1).V

    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
       
        dYDiv = 1/dY2
       
        zSlope2 = dZ2 * dYDiv
       
        Slope2 = dX2 * dYDiv
       
        USlope2 = dU2 * dYDiv
        VSlope2 = dV2 * dYDiv
       
        RSlope2 = dR2 * dYDiv
        GSlope2 = dG2 * dYDiv
        BSlope2 = dB2 * dYDiv
       
    else
       
        zSlope2 = 0
       
        Slope2 = 0
       
        USlope2 = 0
        VSlope2 = 0
       
        RSlope2 = 0
        GSlope2 = 0
        BSlope2 = 0
    End if
   
   
    '' interpolate 0 to 2
   
    dZ3 = Triangle.Vertex(0).pos3d.z - Triangle.Vertex(2).pos3d.z
   
    dX3 = Triangle.Vertex(0).pos2d.x - Triangle.Vertex(2).pos2d.x
    dY3 = Triangle.Vertex(0).pos2d.y - Triangle.Vertex(2).pos2d.y
   
    dU3 = Triangle.Vertex(0).U - Triangle.Vertex(2).U
    dV3 = Triangle.Vertex(0).V - Triangle.Vertex(2).V

    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
       
        dYDiv = 1/dY3
       
        zSlope3 = dZ3 * dYDiv
       
        Slope3 = dX3 * dYDiv
       
        USlope3 = dU3 * dYDiv
        VSlope3 = dV3 * dYDiv
       
        RSlope3 = dR3 * dYDiv
        GSlope3 = dG3 * dYDiv
        BSlope3 = dB3 * dYDiv
       
    else
       
        zSlope3 = 0
       
        Slope3 = 0
       
        USlope3 = 0
        VSlope3 = 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 CurU1=Triangle.Vertex(0).U, CurU2=Triangle.Vertex(0).U,_
                  CurV1=Triangle.Vertex(0).V, CurV2=Triangle.Vertex(0).V
   
    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
   
    dim as single CurZ1=Triangle.Vertex(0).pos3d.z, CurZ2=Triangle.Vertex(0).pos3d.z
   
    CurZ1 += Triangle.Parent_Center.z
    CurZ2 += Triangle.Parent_Center.z
   
    'BufferIter = Triangle.Vertex(0).pos2d.y * xRes
   
    For y as integer = Triangle.Vertex(0).pos2d.y to Triangle.Vertex(1).pos2d.y-1
       
        TSLine(CurX1,CurX2,y,CurU1,CurV1,CurU2,CurV2, CurZ1, CurZ2, Texture,CurR1,CurR2,CurG1,CurG2,CurB1,CurB2)
       
        CurZ1 += zSlope1
        CurZ2 += zSlope3
       
        CurU1 += USlope1
        CurU2 += USlope3
        CurV1 += VSlope1
        CurV2 += VSlope3
       
        CurX1 += Slope1
        CurX2 += Slope3
       
        CurR1 += RSlope1
        CurR2 += RSlope3
        CurG1 += GSlope1
        CurG2 += GSlope3
        CurB1 += BSlope1
        CurB2 += BSlope3
       
        'BufferIter += xRes
       
    Next
   
    '' down
   
    CurZ1 = Triangle.Vertex(1).pos3d.z+Triangle.Parent_Center.z
   
    CurU1 = Triangle.Vertex(1).U
    CurV1 = Triangle.Vertex(1).V
   
    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
       
        TSLine(CurX1,CurX2,y,CurU1,CurV1,CurU2,CurV2, CurZ1, CurZ2, Texture,CurR1,CurR2,CurG1,CurG2,CurB1,CurB2)
       
        CurZ1 += zSlope2
        CurZ2 += zSlope3
       
        CurX1 += Slope2
        CurX2 += Slope3
       
        CurU1 += USlope2
        CurU2 += USlope3
        CurV1 += VSlope2
        CurV2 += VSlope3
       
        CurR1 += RSlope2
        CurR2 += RSlope3
        CurG1 += GSlope2
        CurG2 += GSlope3
        CurB1 += BSlope2
        CurB2 += BSlope3
       
    Next
   
End Sub

Sub Rotate(obj as objectT,Tx as single, Ty as single, Tz as single)
   
    dim as single tmpX,tmpY,TmpZ,normX,normY,normZ
    dim as single VnormX,VnormY,VnormZ
   
    For i as integer = 1 to obj.NB_triangles
        For j as integer = 0 to 2
           
            '' Points
            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
                   
       
            '' Vertex normals
            VnormY = obj.Triangle(i).Vertex(j).Gouraud_Normal.y * cos(Tx) - obj.Triangle(i).Vertex(j).Gouraud_Normal.z * sin(Tx)
            VnormZ = obj.Triangle(i).Vertex(j).Gouraud_Normal.z * cos(Tx) + obj.Triangle(i).Vertex(j).Gouraud_Normal.y * sin(Tx)
            obj.Triangle(i).Vertex(j).Gouraud_Normal.y = VnormY
            obj.Triangle(i).Vertex(j).Gouraud_Normal.z = VnormZ
           
            VnormZ = obj.Triangle(i).Vertex(j).Gouraud_Normal.z * cos(Ty) - obj.Triangle(i).Vertex(j).Gouraud_Normal.x * sin(Ty)
            VnormX = obj.Triangle(i).Vertex(j).Gouraud_Normal.x * cos(Ty) + obj.Triangle(i).Vertex(j).Gouraud_Normal.z * sin(Ty)
            obj.Triangle(i).Vertex(j).Gouraud_Normal.x = VnormX

            VnormX = obj.Triangle(i).Vertex(j).Gouraud_Normal.x * cos(Tz) - obj.Triangle(i).Vertex(j).Gouraud_Normal.y * sin(Tz)
            VnormY = obj.Triangle(i).Vertex(j).Gouraud_Normal.y * cos(Tz) + obj.Triangle(i).Vertex(j).Gouraud_Normal.x * sin(Tz)
           
            obj.Triangle(i).Vertex(j).Gouraud_Normal.x = VnormX
            obj.Triangle(i).Vertex(j).Gouraud_Normal.y = VnormY
            obj.Triangle(i).Vertex(j).Gouraud_Normal.z = VnormZ
        Next
       
        '' normals
        NormY = obj.Triangle(i).Normal.y * cos(Tx) - obj.Triangle(i).Normal.z * sin(Tx)
        NormZ = obj.Triangle(i).Normal.z * cos(Tx) + obj.Triangle(i).Normal.y * sin(Tx)
        obj.Triangle(i).Normal.y = NormY
        obj.Triangle(i).Normal.z = NormZ
       
        NormZ = obj.Triangle(i).Normal.z * cos(Ty) - obj.Triangle(i).Normal.x * sin(Ty)
        NormX = obj.Triangle(i).Normal.x * cos(Ty) + obj.Triangle(i).Normal.z * sin(Ty)
        obj.Triangle(i).Normal.x = NormX
       
        NormX = obj.Triangle(i).Normal.x * cos(Tz) - obj.Triangle(i).Normal.y * sin(Tz)
        NormY = obj.Triangle(i).Normal.y * cos(Tz) + obj.Triangle(i).Normal.x * sin(Tz)
           
        obj.Triangle(i).Normal.x = NormX
        obj.Triangle(i).Normal.y = NormY
        obj.Triangle(i).Normal.z = NormZ
       
    Next
   
End sub

Function FPS() as integer
   
    dim as integer _curfps
   
    If Timer - FPS_t <= 1 then
       
        FPS_counter += 1
       
        Return -1
       
    else
       
        _CurFPS = FPS_Counter/(Timer - FPS_t)
       
        FPS_counter = 0
        FPS_t = Timer
       
        Return _CurFPS
       
    End if
End Function

Function GenerateCube(x0 as integer,y0 as integer,z0 as integer,Size as integer) as objectT
   
    Dim as ObjectT obj
    Dim as Single Size_2 = Size/2
   
    obj.Center.x=x0
    obj.Center.y=y0
    obj.Center.z=z0
   
    obj.nb_triangles = 12 '' 12 !
   
    '' Defining color white/grey
    For i as integer = 1 to obj.nb_triangles
        for j as integer = 0 to 2
            obj.triangle(i).Vertex(j).originalColor.r = 255
            obj.triangle(i).Vertex(j).originalColor.g = 255
            obj.triangle(i).Vertex(j).originalColor.b = 255
        next
    next
   
   
    '' Face 1
    obj.triangle(1).Vertex(0).U = 1
    obj.triangle(1).Vertex(0).V = 0
    obj.triangle(1).Vertex(0).pos3d.x = Size_2
    obj.triangle(1).Vertex(0).pos3d.y = Size_2
    obj.triangle(1).Vertex(0).pos3d.z = Size_2
   
    obj.triangle(1).Vertex(2).U = 0
    obj.triangle(1).Vertex(2).V = 0
    obj.triangle(1).Vertex(2).pos3d.x = -Size_2
    obj.triangle(1).Vertex(2).pos3d.y = Size_2
    obj.triangle(1).Vertex(2).pos3d.z = Size_2

Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Shockwave

That looks really, really, really nice.

Well done :)
Shockwave ^ Codigos
Challenge Trophies Won:

Hezad

thanks a lot :)

Here's just a little pic resulting from a glitch I had when coding a GenerateSphere() sub, I like it :p

Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Hezad

Update :


Vector Light replaced by Omni Light



~20 rotating cubes with an omni light at the center of the screen

image hosted on Kristopher Windsor's image hosting service :p
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Shockwave

Where's the file? :) Looks nice but I want to see it in action :D
Shockwave ^ Codigos
Challenge Trophies Won:

Hezad

uhuh oki :D

here it is ^^

and the code :

edit : erm the code must be too long, the code marks cut it :S but if anyone wants to see it, it's in the .rar :)
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Shockwave

That's working really nicely :)

This computer is a P4 3.0 Ghz, but the computer is quite old and the frame rate is perfectly ok here, it does a fairly steady 29 - 32 fps.

I suspect that it would be a lot faster without the lightsourcing :) The lightsourcing looks very nice though.
Shockwave ^ Codigos
Challenge Trophies Won:

Hezad

thanks :) Well yeah, if I get off the light calculations and do only a texture mapping i get ~40FPS instead of 30 normally :)

But if cubes are a bit larger or nearer, it's getting worse lol I get ~10 FPS and even 3/4 FPS if they fill the whole screen :S

optimization .. :p
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Shockwave

#29
Optimization.. Well, this is coming I guess. and there are a few things that you can do to optimise it.

I think that what you have done there is achieved by less than 1% of people who learn programming, you've progressed a lot and I bet Relsoft will be really happy when he sees what you made since you read his tutorial, he is a member here and I know he likes to show people how to code things.

Anyway onto your demo, the two things that are a problem are the speed and texture warping.

Texture warping is unavoidable with affine texture mapping like you are doing.
It is more noticeable when there is a lot of perspective on the surface you are drawing, for example, some vertex is deep into the screen and other vertices are close, the texture seems to slide around the polygon.

There are solutions, firstly one of the fastest ways is to subdivide the surface into several smaller triangles and subdivide the UV's too, so in practice you might render


    /\
  /    \
------


Like this;


     *
    /_\
  / \/ \
  ------


(apologies for the dodgy ascii), this means that the warping effect is less noticeable.

Or you could use a perspective correct algorithm,  with this algorithm and as a side effect you get the z-co-ordinate of each pixel for your Z-Buffer.

Another thing you will probably want to look into is clipping and definately mip-mapping.

Both will increase your speed, clipping algorithms will enable you to chop up polygons and thereby discard geometary that is not visible.

Mip mapping you will generate a set of texture maps ranging from small size to large for your polygon and perform the cross-product equation on your polygon to determine it's area so that you can select the texture map that best fits the area of the polygon you are about to draw.

Smaller texture maps are faster, using mip mapping will also help avoid "dancing pixels" which are typically visible on small polygons where the routine is accessing a large texture map. These artifacts appear as flickering dots.

Anyway that's probably more than enough to be going along with, I reccomend that you start off with perspective correct textures :) Please do post if you need help or just to let us know how you are getting along. I for one am really enjoying this topic!
Shockwave ^ Codigos
Challenge Trophies Won:

Hezad

Hey :) I was coding something to enjoy my engine start (:p) but I didn't read what you just written while I was doing that, so the thing i'll attach with this post hasn't any of the optimizations you just told me.

So first, i'll answer you :)

QuoteI think that what you have done there is achieved by less than 1% of people who learn programming, you've progressed a lot and I bet Relsoft will be really happy when he sees what you made since you read his tutorial, he is a member here and I know he likes to show people how to code things.

Well, thanks ! this kind of comments surely puts me on the motivation track ! And Relsoft already commented it on the freebasic forums.
Even if I know it's far from a perfect thing, I have to admit I'm pretty proud (yeah auto-satisfaction .. :p) of what I have done so far but you know, sometimes you're so glad about some self-made stuff that you don't see crucial flaws. Until now, I think I saw them and you (and other people) really helped me to fix them.

So once again, thanks !!


QuoteTexture warping is unavoidable with affine texture mapping like you are doing.
It is more noticeable when there is a lot of perspective on the surface you are drawing, for example, some vertex is deep into the screen and other vertices are close, the texture seems to slide around the polygon.

(...)
Totally agree, I really need to code the corrected perspective stuff. It's already on my todo list and I spent some time with my friend "internet" to understand it :p Anyway, your explications are totally helpful and I think it'll help me to work on it !

Oh ! And don't worry about the ASCII diagram, It totally makes sense :)


QuoteAnother thing you will probably want to look into is clipping
Right ! But before, I need to make sure I totally understand/recode my coordinates system :the Z-buffer algo + the projection routine work but use some really weird Z constants and/or subtractions. So I really need to see what's going on in there before thinking about clipping :p
(By clipping, I guess you're speaking about not calculating poly's outside the viewing frustum  ?)


Quoteand definately mip-mapping.
QuoteMip mapping you will generate a set of texture maps ranging from small size to large for your polygon and perform the cross-product equation on your polygon to determine it's area so that you can select the texture map that best fits the area of the polygon you are about to draw.

Smaller texture maps are faster, using mip mapping will also help avoid "dancing pixels" which are typically visible on small polygons where the routine is accessing a large texture map. These artifacts appear as flickering dots.

!! I heard of mip-mapping so often .. I didn't understand in which way it could be helpful.. Now I do ! It has to be on my todo list :D Once again, Really clear explanation :)


QuoteAnyway that's probably more than enough to be going along with, I reccomend that you start off with perspective correct textures Smiley Please do post if you need help or just to let us know how you are getting along. I for one am really enjoying this topic!

perspective correct texture mapping is the first item on my list :D
I will post if I have questions (and I'm pretty sure i'll have :p), thanks !
And I'm glad you like this topic, really ! :)



To finish, I'll post the thing I spoke about at the beginning of this post, the Plasma Cube ! :D Well I already saw that kind of stuff pretty often but whatever ^^

Attached : Screenshot + Rar(Src+Exe)

thanks again Shockwave !

Bye :)
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Jim

The other thing you need to look at speedwise is you are doing an incredible number of Single->Int conversions in your code,  potentially a dozen per pixel.  That is not a fast thing to do, so you might want to think about how you can do it all in integers.
If you backface cull, you won't see all the insides of the objects too - that will halve the number of faces you are considering.

Jim
Challenge Trophies Won:

Hezad

Quoteyou might want to think about how you can do it all in integers

Yeah sure ! thanks I didn't think about that.


QuoteIf you backface cull, you won't see all the insides of the objects too
hm ? I don't understand :p Since faces are only drawn once, If I backface cull a face, it won't be calculated anyway, no ?
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Shockwave

Quote from: Hezad on August 27, 2008
QuoteIf you backface cull, you won't see all the insides of the objects too
hm ? I don't understand :p Since faces are only drawn once, If I backface cull a face, it won't be calculated anyway, no ?

You can either use the normal to backface cull (is it pointing in or out) or just use the cross-product equation to determine if the points are clockwise or counter clockwise (clue: the result is either positive or negative), then you can decide whether to draw the polygon or not.

This means that for a cube which is made from 12 triangles, potentially you will only need to draw a maximum of 6 of them.

Rotating the vertices and doing a cross product calc is cheap when compared to drawing a texture mapped polygon, so what Jim is saying is that the calcs of rotating the object and doing that simple check to see if you should draw the polygon will speed things up a lot.

Quote(By clipping, I guess you're speaking about not calculating poly's outside the viewing frustum  ?)

I mean not drawing polys or parts of polys that lie outside the view frustrum. :)

Btw, the plasma cube looks really great! Nice colour choice.
Shockwave ^ Codigos
Challenge Trophies Won:

Jim

If you clip the polygons, either in 3d (better) or in 2d screen space, then you can remove ALL the If checks that test if the triangle starts off the screen or if a pixel is off the screen.  Doing all that stuff up front makes the hard bit of drawing triangles simpler.

Jim
Challenge Trophies Won:

Clyde

Yeah very cool plasma cube dude.

Welldone on your efforts,
Clyde
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Hezad

QuoteRotating the vertices and doing a cross product calc is cheap when compared to drawing a texture mapped polygon, so what Jim is saying is that the calcs of rotating the object and doing that simple check to see if you should draw the polygon will speed things up a lot.

QuoteIf you clip the polygons, either in 3d (better) or in 2d screen space, then you can remove ALL the If checks that test if the triangle starts off the screen or if a pixel is off the screen.  Doing all that stuff up front makes the hard bit of drawing triangles simpler.

So if I understand correctly (and sorry if it's not the case :p), I should verify if the current poly (or pixel?) is in the viewing frustum (in 3d) and then, calculate (Poly Normal [Dot] View Normal) to make sure the poly is visible (and if it's not, I "forget" it for the projection/lighting/rendering calculations) ?

thanks for your answers and for the comments about the plasma cube :)
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com

Xalthorn

Wow, this is some seriously impressive work and from what I gather by reading through the posts, you are a literal sponge for information.  You're able to keep progressing by answering sensible questions and acting on the responses.  Something to be encouraged and celebrated.

:clap:

Challenge Trophies Won:

Jim

Quote
If you clip the polygons, either in 3d (better) or in 2d screen space, then you can remove ALL the If checks that test if the triangle starts off the screen or if a pixel is off the screen.  Doing all that stuff up front makes the hard bit of drawing triangles simpler.
QuoteSo if I understand correctly (and sorry if it's not the case :p), I should verify if the current poly (or pixel?) is in the viewing frustum (in 3d) and then, calculate (Poly Normal [Dot] View Normal) to make sure the poly is visible (and if it's not, I "forget" it for the projection/lighting/rendering calculations) ?
Not really.
In 2d clipping, you do the whole process that you are currently doing, but just before you render the triangle you work out whether any of it is off screen.  If it is, then you can clip the triangle against the screen's rectangle and that will give you a set of triangles which can be rendered without any If testing.

In 3d clipping, you do that process in 3d against the pyramid which is your viewing frustum (imagine a square-based pyramid with the point at the camera and the rectangular base being your far-clip plane).  You can work out, before projection, which polygons are inside that volume.  The advantage of this is that you don't get range error problems when you do the perspective calculation - and you can't do 2d clipping without doing perspective - so you save yourself some real problems.

Jim

Challenge Trophies Won:

Hezad

Xalthorn > thanks :D Well I ask questions so if people answer me, I have to take their answers into account :)

Jim > ok thanks, I start to understand your point :p But sorry for this last question but since I am not sure about it, I prefer to ask :
when you say
Quoteyou can clip the triangle against the screen's rectangle and that will give you a set of triangles which can be rendered without any If testing.
Do you mean I discard all the triangle if a part of it must be clipped (but it could appear suddenly in the screen if so, no ?) or shall I "just" don't draw the pixels out of screen ?
Because right now, Just before drawing the pixel, I do a "basic" 2D clipping :
If x>0 and x<xRes and y>0 and y<yRes then putPixel

So do you mean doing this but in 3D ? Or Did I totally misunderstand once again ? Sorry for insisting with it but in fact I guess I don't understand how I could verify whether the poly is in screen/viewing frustum or not without any if testing ..
Music + Coding :
http://Hezad.no-ip.org

Hosting / Hébergement :
www.hezad.com