Advertisement
Guest User

Untitled

a guest
Aug 9th, 2015
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 7.30 KB | None | 0 0
  1. import derelict.sdl2.sdl;
  2. import std.stdio;
  3. import std.array;
  4. import std.traits;
  5. import std.math;
  6. import std.datetime;
  7. import std.concurrency;
  8. import std.traits;
  9.  
  10. struct vec2 {
  11.     float x, y;
  12.  
  13.     vec2 opBinary(string op, T)(T rhs) {
  14.         static if(op == "+" || op == "-" || op == "*" || op == "/") {
  15.             static if(is(T == vec2)) {
  16.                 mixin("return vec2(x $ rhs.x, y $ rhs.y);".replace("$", op));
  17.             } else static if(isNumeric!T) {
  18.                 mixin("return vec2(x $ rhs, y $ rhs);".replace("$", op));
  19.             } else {
  20.                 static assert(0, "Invalid use of operator: vec2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  21.             }
  22.         }
  23.     }
  24.  
  25.     void opOpAssign(string op, T)(T rhs) {
  26.         static if(op == "+" || op == "-" || op == "*" || op == "/") {
  27.             static if(is(T == vec2)) {
  28.                 mixin("x $= rhs.x; y $= rhs.y;".replace("$", op));
  29.             } else static if(isNumeric!T) {
  30.                 mixin("x $= rhs; y $= rhs;".replace("$", op));
  31.             } else {
  32.                 static assert(0, "Invalid use of operator: vec2 " ~ op ~ "= " ~ fullyQualifiedName!T ~ ".");
  33.             }
  34.         }
  35.     }
  36. }
  37.  
  38. struct vec3 {
  39.     float x, y, z;
  40.  
  41.     vec3 opBinary(string op, T)(T rhs) {
  42.         static if(op == "+" || op == "-" || op == "*" || op == "/") {
  43.             static if(is(T == vec3)) {
  44.                 mixin("return vec3(x $ rhs.x, y $ rhs.y, z $ rhs.z);".replace("$", op));
  45.             } else static if(isNumeric!T) {
  46.                 mixin("return vec3(x $ rhs, y $ rhs, z $ rhs);".replace("$", op));
  47.             } else {
  48.                 static assert(0, "Invalid use of operator: vec3 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  49.             }
  50.         }
  51.     }
  52.  
  53.     void opOpAssign(string op, T)(T rhs) {
  54.         static if(op == "+" || op == "-" || op == "*" || op == "/") {
  55.             static if(is(T == vec3)) {
  56.                 mixin("x $= rhs.x; y $= rhs.y; z $= rhs.z;".replace("$", op));
  57.             } else static if(isNumeric!T) {
  58.                 mixin("x $= rhs; y $= rhs; z $= rhs;".replace("$", op));
  59.             } else {
  60.                 static assert(0, "Invalid use of operator: vec3 " ~ op ~ "= " ~ fullyQualifiedName!T ~ ".");
  61.             }
  62.         }
  63.     }
  64. }
  65.  
  66. struct mat2 {
  67.     float
  68.         m0, m1,
  69.         m2, m3;
  70.  
  71.     auto opBinary(string op, T)(T rhs) {
  72.         static if(is(T == vec2)) {
  73.             static if(op == "*") {
  74.                 return vec2(
  75.                     m0 * rhs.x + m1 * rhs.y,
  76.                     m2 * rhs.x + m3 * rhs.y);
  77.             } else {
  78.                 static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  79.             }
  80.         } else {
  81.             static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  82.         }
  83.     }
  84. }
  85.  
  86. mat2 getRotMat2(float a) {
  87.     return mat2(cos(a), -sin(a), sin(a), cos(a));
  88. }
  89.  
  90. struct mat3 {
  91.     float
  92.         m0, m1, m2,
  93.         m3, m4, m5,
  94.         m6, m7, m8;
  95.  
  96.     auto opBinary(string op, T)(T rhs) {
  97.         static if(is(T == vec3)) {
  98.             static if(op == "*") {
  99.                 return vec3(
  100.                     m0 * rhs.x + m1 * rhs.y + m2 * rhs.z,
  101.                     m3 * rhs.x + m4 * rhs.y + m5 * rhs.z,
  102.                     m6 * rhs.x + m7 * rhs.y + m8 * rhs.z);
  103.             } else {
  104.                 static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  105.             }
  106.         } else {
  107.             static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
  108.         }
  109.     }
  110. }
  111.  
  112. mat3 getRotMat3X(float a) {
  113.     return mat3(1,          0,          0,
  114.                 0,          cos(a),     -sin(a),
  115.                 0,          sin(a),     cos(a));
  116. }
  117.  
  118. mat3 getRotMat3Y(float a) {
  119.     return mat3(cos(a),     0,          sin(a),
  120.                 0,          1,          0,
  121.                 -sin(a),    0,          cos(a));
  122. }
  123.  
  124. mat3 getRotMat3Z(float a) {
  125.     return mat3(cos(a),     -sin(a),    0,
  126.                 sin(a),     cos(a),     0,
  127.                 0,          0,          1);
  128. }
  129.  
  130. float length(vec2 v) {
  131.     return sqrt(v.x ^^ 2 + v.y ^^ 2);
  132. }
  133.  
  134. float length(vec3 v) {
  135.     return sqrt(v.x ^^ 2 + v.y ^^ 2 + v.z ^^ 2);
  136. }
  137.  
  138. vec2 normalize(vec2 v) {
  139.     float len = length(v);
  140.     return vec2(v.x/len, v.y/len);
  141. }
  142.  
  143. vec3 normalize(vec3 v) {
  144.     float len = length(v);
  145.     return vec3(v.x/len, v.y/len, v.z/len);
  146. }
  147.  
  148. struct HitInfo {
  149.     float dist;
  150.     vec3 color;
  151. }
  152.  
  153. const vec3 circleColor = vec3(1., 0.5, 0.);
  154. const float circleRad = 0.5;
  155. const uint PIXEL_SIZE = 1;
  156. const float EPSILON = 0.001;
  157. const float MAX_DIST = 50;
  158.  
  159. HitInfo sphere(vec3 r, float rad) {
  160.     return HitInfo(length(r) - rad, vec3(0, 1, 0));
  161. }
  162.  
  163. HitInfo box(vec3 r, vec3 s) {
  164.     return HitInfo(fmax(fmax(abs(r.x) - s.x, abs(r.y) - s.y), abs(r.z) - s.z), vec3(1, 0, 0));
  165. }
  166.  
  167. HitInfo map(vec3 r) {
  168.     auto h1 = sphere(r, 1);
  169.     auto h2 = box(r, vec3(0.8, 0.8, 0.8));
  170.     float d;
  171.     if(h1.dist < h2.dist) {
  172.         return h1;
  173.     }
  174.     return h2;
  175. }
  176.  
  177. static uint numThreads = 8;
  178.  
  179. void main() {
  180.     DerelictSDL2.load();
  181.     SDL_Window* window = SDL_CreateWindow("TEST", 200, 200, PIXEL_SIZE*128, PIXEL_SIZE*72, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
  182.     shared(SDL_Surface)* surface = cast(shared(SDL_Surface)*)SDL_GetWindowSurface(window);
  183.  
  184.     SDL_Event event;
  185.     auto quit = false;
  186.  
  187.     auto start = Clock.currTime;
  188.     uint frames = 0;
  189.  
  190.     while (!quit) {
  191.         auto time = (cast(float)(Clock.currTime - start).total!"nsecs")/1000000000;
  192.         while(SDL_PollEvent(&event)) {
  193.             if (event.type == SDL_QUIT) {
  194.                 writefln("%s", frames/time);
  195.                 quit = true;
  196.             }
  197.         }
  198.        
  199.         for(uint i = 0; i < numThreads; i++) {
  200.             auto t = spawnLinked(&drawPixels, i, surface.w/PIXEL_SIZE, surface.h/PIXEL_SIZE, time, surface);
  201.         }
  202.         for(uint i = 0; i < numThreads; i++) {
  203.             try {
  204.                 receive({ });
  205.             } catch {}
  206.         }
  207.         frames++;
  208.         SDL_UpdateWindowSurface(window);
  209.     }
  210. }
  211.  
  212. void drawPixels(uint id, uint w, uint h, float time, shared(SDL_Surface)* surface) {
  213.     auto res = vec2(w, h);
  214.     for(uint j = id; j < w * h; j += numThreads) {
  215.         auto x = j % w;
  216.         auto y = j / w;
  217.         auto coord = vec2(x, y);
  218.         auto color = pixel(coord, res, time);
  219.         ubyte r = cast(ubyte)(color.x * 255);
  220.         ubyte g = cast(ubyte)(color.y * 255);
  221.         ubyte b = cast(ubyte)(color.z * 255);
  222.         SDL_Rect rect = SDL_Rect(x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
  223.         SDL_FillRect(cast(SDL_Surface*)surface, &rect, r << 16 | g << 8 | b);
  224.     }
  225. }
  226.  
  227. vec3 pixel(vec2 coord, vec2 res, float time) {
  228.     vec2 uv = coord / res;
  229.     uv.x *= res.x/res.y;
  230.     uv.x -= res.x/res.y/2;
  231.     uv.y -= 0.5;
  232.     uv *= 2;
  233.  
  234.     // Rotation
  235.     vec3 ro = vec3(0, 0, -2);
  236.     ro = getRotMat3Y(time) * ro;
  237.     ro = getRotMat3Z(time) * ro;
  238.     ro = getRotMat3X(time) * ro;
  239.    
  240.     vec3 rd = normalize(vec3(uv.x, uv.y, 1));
  241.     rd = getRotMat3Y(time) * rd;
  242.     rd = getRotMat3Z(time) * rd;
  243.     rd = getRotMat3X(time) * rd;
  244.  
  245.     // Raymarching
  246.     float l = 0;
  247.     for(uint i = 0; i < 100; i++) {
  248.         vec3 r = ro + rd * l;
  249.         auto hit = map(r);
  250.  
  251.         if(hit.dist <= EPSILON) {
  252.             return hit.color;
  253.         }
  254.  
  255.         if(l > MAX_DIST) {
  256.             return vec3(0, 0, 0);
  257.         }
  258.  
  259.         l = l + hit.dist;
  260.     }
  261.  
  262.     return vec3(0, 0, 0);
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement