Mercurial > projects > ldc
annotate demos/ray.d @ 1543:21d691518d82
Use TargetRegistry instead of TargetMachineRegistry for Target lookups
This fixes the build for LLVM >= r75774 and will probably break older
LLVM revs.
author | Benjamin Kramer <benny.kra@gmail.com> |
---|---|
date | Wed, 15 Jul 2009 23:01:51 +0200 |
parents | eef8ac26c66c |
children |
rev | line source |
---|---|
165
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
1 import tango.stdc.stdio; |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
2 |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
3 alias char[] string; |
92 | 4 |
5 int atoi(char[] s) { | |
6 int i, fac=1; | |
7 bool neg = (s.length) && (s[0] == '-'); | |
8 char[] a = neg ? s[1..$] : s; | |
9 foreach_reverse(c; a) { | |
10 i += (c-'0') * fac; | |
11 fac *= 10; | |
12 } | |
13 return !neg ? i : -i; | |
14 } | |
15 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
620
diff
changeset
|
16 version(LDC) |
165
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
17 { |
620
718ddecc053c
Fix downs' raytracer demo to use new intrinsics.
Christian Kamm <kamm incasoftware de>
parents:
166
diff
changeset
|
18 pragma(intrinsic, "llvm.sqrt.f64") |
92 | 19 double sqrt(double val); |
165
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
20 } |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
21 else |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
22 { |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
23 import tango.stdc.math; |
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
24 } |
92 | 25 |
26 double delta; | |
27 static this() { delta=sqrt(real.epsilon); } | |
28 | |
29 struct Vec { | |
30 double x, y, z; | |
31 Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); } | |
32 Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); } | |
33 Vec opMul(double a) { return Vec(x*a, y*a, z*a); } | |
34 double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; } | |
35 Vec unitise() { return opMul(1.0/sqrt(dot(*this))); } | |
36 } | |
37 | |
38 struct Pair(T, U) { T first; U second; } | |
39 typedef Pair!(double, Vec) Hit; | |
40 | |
41 struct Ray { Vec orig, dir; } | |
42 | |
43 class Scene { | |
44 //abstract void intersect(ref Hit, ref Ray); | |
45 void intersect(ref Hit, ref Ray) {} | |
46 } | |
47 | |
48 class Sphere : Scene { | |
49 Vec center; | |
50 double radius; | |
51 //mixin This!("center, radius"); | |
52 this(ref Vec c, double r) | |
53 { | |
54 center = c; | |
55 radius = r; | |
56 } | |
57 double ray_sphere(ref Ray ray) { | |
58 auto v = center - ray.orig, b = v.dot(ray.dir), disc=b*b - v.dot(v) + radius*radius; | |
59 if (disc < 0) return double.infinity; | |
60 auto d = sqrt(disc), t2 = b + d; | |
61 if (t2 < 0) return double.infinity; | |
62 auto t1 = b - d; | |
63 return (t1 > 0 ? t1 : t2); | |
64 } | |
65 void intersect(ref Hit hit, ref Ray ray) { | |
66 auto lambda = ray_sphere(ray); | |
67 if (lambda < hit.first) | |
68 hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise); | |
69 } | |
70 } | |
71 | |
72 class Group : Scene { | |
73 Sphere bound; | |
74 Scene[] children; | |
75 //mixin This!("bound, children"); | |
76 this (Sphere s, Scene[] c) | |
77 { | |
78 bound = s; | |
79 children = c; | |
80 } | |
81 void intersect(ref Hit hit, ref Ray ray) { | |
82 auto l = bound.ray_sphere(ray); | |
83 if (l < hit.first) foreach (child; children) child.intersect(hit, ray); | |
84 } | |
85 } | |
86 | |
87 double ray_trace(ref Vec light, ref Ray ray, Scene s) { | |
88 auto hit=Hit(double.infinity, Vec(0, 0, 0)); | |
89 s.intersect(hit, ray); | |
90 if (hit.first == double.infinity) return 0.0; | |
91 auto g = hit.second.dot(light); | |
92 if (g >= 0) return 0.0; | |
93 auto p = ray.orig + ray.dir*hit.first + hit.second*delta; | |
94 auto hit2=Hit(double.infinity, Vec(0, 0, 0)); | |
95 s.intersect(hit2, Ray(p, light*-1.0)); | |
96 return (hit2.first < double.infinity ? 0 : -g); | |
97 } | |
98 | |
99 Scene create(int level, ref Vec c, double r) { | |
100 auto s = new Sphere(c, r); | |
101 if (level == 1) return s; | |
94
61615fa85940
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents:
92
diff
changeset
|
102 Scene[] children; |
61615fa85940
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents:
92
diff
changeset
|
103 children ~= s; |
92 | 104 double rn = 3*r/sqrt(12.0); |
105 for (int dz=-1; dz<=1; dz+=2) | |
106 for (int dx=-1; dx<=1; dx+=2) | |
107 children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2); | |
108 return new Group(new Sphere(c, 3*r), children); | |
109 } | |
110 | |
111 void main(string[] args) { | |
112 int level = (args.length==3 ? args[1].atoi() : 9), | |
113 n = (args.length==3 ? args[2].atoi() : 512), ss = 4; | |
114 auto light = Vec(-1, -3, 2).unitise(); | |
115 auto s=create(level, Vec(0, -1, 0), 1); | |
166
a2c4dc388d5e
[svn r182] Oups, the PGM output for the raytracer demo was borked.
lindquist
parents:
165
diff
changeset
|
116 printf("P5\n%d %d\n255\n", n,n); |
92 | 117 for (int y=n-1; y>=0; --y) |
118 for (int x=0; x<n; ++x) { | |
119 double g=0; | |
120 for (int d=0; d<ss*ss; ++d) { | |
121 auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise(); | |
165
9922b9982552
[svn r181] Updated the raytracer demo by downs to work with tango :) My quick
lindquist
parents:
100
diff
changeset
|
122 g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s); |
92 | 123 } |
124 printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss))); | |
125 } | |
126 } |