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,
"[GScanlines 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");
}
}
|