aboutsummaryrefslogtreecommitdiff
path: root/camera.go
blob: e460cc02275518a5a8a3fccd9921410d6c84d7d5 (plain)
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
63
64
package main

import (
  "fmt"
  "os"
)

type Camera struct {
  ImageWidth uint
  ImageHeight uint
  Centre Vec3
  PDU Vec3
  PDV Vec3
  Pixel00 Vec3
}

func NewCamera(w uint, ar float64) (cam Camera) {
  cam.ImageWidth = w;
  cam.ImageHeight = uint(float64(cam.ImageWidth) / ar);
  if cam.ImageHeight < 1 {
    cam.ImageHeight = 1;
  }

  focal_length := 1.0;
  viewport_height := 2.0;
  viewport_width := viewport_height *
                       float64(cam.ImageWidth) /
                       float64(cam.ImageHeight);
  cam.Centre = Splat(0);

  viewport_u := Vec3{viewport_width, 0, 0};
  viewport_v := Vec3{0, -viewport_height, 0};

  cam.PDU = viewport_u.Div(Splat(float64(cam.ImageWidth)));
  cam.PDV = viewport_v.Div(Splat(float64(cam.ImageHeight)));

  viewport_upperleft := cam.Centre.
                        Sub(Vec3{0, 0, focal_length}).
                        Sub(viewport_u.Div(Splat(2))).
                        Sub(viewport_v.Div(Splat(2)));
  cam.Pixel00 = viewport_upperleft.
                 Add(cam.PDU.Add(cam.PDV).Div(Splat(2)));

  return;
}

func (cam Camera) Render(world Hittable) {
  fmt.Printf("P3\n%d %d\n255\n", cam.ImageWidth, cam.ImageHeight);
  for row := uint(0); row < cam.ImageHeight; row++ {
    fmt.Fprintf(os.Stderr,
                "Scanlines remaining: %3d...",
                (cam.ImageHeight - row));
    for col := uint(0); col < cam.ImageWidth; col++ {
      pixel_centre := cam.Pixel00.
                      Add(cam.PDU.Mul(Splat(float64(col)))).
                      Add(cam.PDV.Mul(Splat(float64(row))));
      ray_direction := pixel_centre.Sub(cam.Centre);
      ray := Ray{cam.Centre, ray_direction}
      pixel_colour := ray.Colour(world);
      fmt.Printf("%s    ", pixel_colour.ToPPM());
    }
    fmt.Printf("\n");
  }
}