Advertisement
Guest User

Untitled

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