예제 #1
0
파일: main.go 프로젝트: quarnster/gorays
func main() {
	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	g := vector.Vector{X: -5.5, Y: -16, Z: 0}.Normalize()
	a := vector.Vector{X: 0, Y: 0, Z: 1}.CrossProduct(g).Normalize().Scale(0.002)
	b := g.CrossProduct(a).Normalize().Scale(0.002)
	c := a.Add(b).Scale(-256).Add(g)

	img := image.NewRGBA(image.Rect(0, 0, *width, *height))

	const (
		R = iota
		G
		B
		A
	)

	pos := 0
	invheight := 1.0 / float32(*height-1)
	s := time.Now()
	for y := (*height - 1); y >= 0; y-- {
		fmt.Printf("%.2f%%\r", 100*(1-invheight*float32(y)))
		for x := (*width - 1); x >= 0; x-- {
			p := vector.Vector{X: 13, Y: 13, Z: 13}

			for i := 0; i < 64; i++ {
				t := a.Scale(Rand() - 0.5).Scale(99).Add(b.Scale(Rand() - 0.5).Scale(99))
				orig := vector.Vector{X: 17, Y: 16, Z: 8}.Add(t)
				dir := t.Scale(-1).Add(a.Scale(Rand() + float64(x)).Add(b.Scale(float64(y) + Rand())).Add(c).Scale(16)).Normalize()
				p = sampler(orig, dir).Scale(3.5).Add(p)
			}

			img.Pix[pos+R] = uint8(p.X)
			img.Pix[pos+G] = uint8(p.Y)
			img.Pix[pos+B] = uint8(p.Z)
			img.Pix[pos+A] = 0xff
			pos += 4
		}
	}
	e := time.Since(s)
	pixels := (*width) * (*height)
	fmt.Printf("Traced %d pixels in %s, %s/pixel\n", pixels, e, e/time.Duration(pixels))
	f, err := os.Create(outimage)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	if err = png.Encode(f, img); err != nil {
		log.Fatalln(err)
	}
}
예제 #2
0
파일: main.go 프로젝트: purcaro/gorays
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *procs < 1 {
		log.Fatalf("Procs (%v) needs to be >= 1", *procs)
	}

	fmt.Printf("P6 %v %v 255 ", *width, *height)

	bytes := make([]byte, 3**width**height)

	g := vector.Vector{X: -5.5, Y: -16, Z: 0}.Normalize()
	a := vector.Vector{X: 0, Y: 0, Z: 1}.CrossProduct(g).Normalize().Scale(0.002)
	b := g.CrossProduct(a).Normalize().Scale(0.002)
	c := a.Add(b).Scale(-256).Add(g)

	rows := make(chan row, *height)

	var wg sync.WaitGroup
	wg.Add(*procs)
	for i := 0; i < *procs; i++ {
		go worker(a, b, c, bytes, rows, &wg)
	}

	for y := (*height - 1); y >= 0; y-- {
		rows <- row(y)
	}
	close(rows)
	wg.Wait()

	if _, err := os.Stdout.Write(bytes); err != nil {
		log.Panic(err)
	}
}