| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | v3
Project(f32 AspectRatio,f32 FocalLength, v3 P)
{
    v3 TransformedP;
    
    TransformedP.x = FocalLength*P.x / P.z;
    TransformedP.y = FocalLength*P.y*AspectRatio / P.z;
    
    return TransformedP;
}
void
GameUpdateAndRender(game_backbuffer *Backbuffer, controller *Input)
{
    
    v3 FrontFaceV0 = v3f(400.0f, 200.0f, 2.0f);
    v3 FrontFaceV1 = v3f(400.0f, 250.0f, 2.0f);
    v3 FrontFaceV2 = v3f(550.0f, 250.0f, 2.0f);
    
    v3 FrontFaceV00 = v3f(400.0f, 200.0f, 2.0f);
    v3 FrontFaceV01 = v3f(550.0f, 200.0f, 2.0f);
    v3 FrontFaceV02 = v3f(550.0f, 250.0f, 2.0f);
    
    v3 Vertices[6] = 
    {
        FrontFaceV0, FrontFaceV1, FrontFaceV2,
        FrontFaceV00, FrontFaceV01, FrontFaceV02
    };
    
    persist f32 Angle = 0.001f;
    
    
    ClearBackbuffer(Backbuffer);
    
    persist f32 ZOffset = 1.0f;
    if(Input->Controller[0].ButtonUp.IsDown)
    {
        ZOffset+=0.01f;
    }
    if(Input->Controller[0].ButtonDown.IsDown)
    {
        ZOffset-=0.01f;
    }
    
    
    f32 AspectRatio = (f32)WINDOW_WIDTH / (f32)WINDOW_HEIGHT;
    f32 FocalLength = 1.0f;
    
    for(u32 VerticesIndex = 0;
        VerticesIndex < CountOf(Vertices);
        VerticesIndex++)
    {
        Vertices[VerticesIndex].z = ZOffset;
        Vertices[VerticesIndex] = Project(AspectRatio, FocalLength, Vertices[VerticesIndex]);
    }
    
    DrawTriangle(Backbuffer, Vertices[0], Vertices[1], Vertices[2], 0x00FF00);
    DrawTriangle(Backbuffer, Vertices[3], Vertices[4], Vertices[5], 0x00FF00);
    
    Angle += 0.001f;
}
 | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |    for(u32 VerticesIndex = 0;
        VerticesIndex < CountOf(Vertices);
        VerticesIndex++)
    {
        Vertices[VerticesIndex].z = ZOffset;
        
        // NOTE(shvayko): Projection
        Vertices[VerticesIndex] = Project(AspectRatio, FocalLength, Vertices[VerticesIndex]);
        Vertices[VerticesIndex] = Vertices[VerticesIndex] + CENTER_OF_PROJECTION;
        
        // TODO(shvayko): Clipping
        
        // TODO(shvayko): Perspective divide(Divide by W = 1)
        
       // TODO(shvayko): Map the NDC coordinates into the window
    }
    
   // Rasterization stage
 | 
ExTray2020
Also I don't understand why is pespective divide transforms from clip space into NDC space by only dividing each component by w (typically w = 1)