Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import derelict.sdl2.sdl;
- import std.stdio;
- import std.array;
- import std.traits;
- import std.math;
- import std.datetime;
- struct vec2 {
- float x, y;
- vec2 opBinary(string op, T)(T rhs) {
- static if(op == "+" || op == "-" || op == "*" || op == "/") {
- static if(is(T == vec2)) {
- mixin("return vec2(x $ rhs.x, y $ rhs.y);".replace("$", op));
- } else static if(isNumeric!T) {
- mixin("return vec2(x $ rhs, y $ rhs);".replace("$", op));
- } else {
- static assert(0, "Invalid use of operator: vec2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- void opOpAssign(string op, T)(T rhs) {
- static if(op == "+" || op == "-" || op == "*" || op == "/") {
- static if(is(T == vec2)) {
- mixin("x $= rhs.x; y $= rhs.y;".replace("$", op));
- } else static if(isNumeric!T) {
- mixin("x $= rhs; y $= rhs;".replace("$", op));
- } else {
- static assert(0, "Invalid use of operator: vec2 " ~ op ~ "= " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- }
- struct vec3 {
- float x, y, z;
- vec3 opBinary(string op, T)(T rhs) {
- static if(op == "+" || op == "-" || op == "*" || op == "/") {
- static if(is(T == vec3)) {
- mixin("return vec3(x $ rhs.x, y $ rhs.y, z $ rhs.z);".replace("$", op));
- } else static if(isNumeric!T) {
- mixin("return vec3(x $ rhs, y $ rhs, z $ rhs);".replace("$", op));
- } else {
- static assert(0, "Invalid use of operator: vec3 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- void opOpAssign(string op, T)(T rhs) {
- static if(op == "+" || op == "-" || op == "*" || op == "/") {
- static if(is(T == vec3)) {
- mixin("x $= rhs.x; y $= rhs.y; z $= rhs.z;".replace("$", op));
- } else static if(isNumeric!T) {
- mixin("x $= rhs; y $= rhs; z $= rhs;".replace("$", op));
- } else {
- static assert(0, "Invalid use of operator: vec3 " ~ op ~ "= " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- }
- struct mat2 {
- float
- m0, m1,
- m2, m3;
- auto opBinary(string op, T)(T rhs) {
- static if(is(T == vec2)) {
- static if(op == "*") {
- return vec2(
- m0 * rhs.x + m1 * rhs.y,
- m2 * rhs.x + m3 * rhs.y);
- } else {
- static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- } else {
- static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- mat2 getRotMat2(float a) {
- return mat2(cos(a), -sin(a), sin(a), cos(a));
- }
- struct mat3 {
- float
- m0, m1, m2,
- m3, m4, m5,
- m6, m7, m8;
- auto opBinary(string op, T)(T rhs) {
- static if(is(T == vec3)) {
- static if(op == "*") {
- return vec3(
- m0 * rhs.x + m1 * rhs.y + m2 * rhs.z,
- m3 * rhs.x + m4 * rhs.y + m5 * rhs.z,
- m6 * rhs.x + m7 * rhs.y + m8 * rhs.z);
- } else {
- static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- } else {
- static assert(0, "Invalid use of operator: mat2 " ~ op ~ " " ~ fullyQualifiedName!T ~ ".");
- }
- }
- }
- mat3 getRotMat3X(float a) {
- return mat3(1, 0, 0,
- 0, cos(a), -sin(a),
- 0, sin(a), cos(a));
- }
- mat3 getRotMat3Y(float a) {
- return mat3(cos(a), 0, sin(a),
- 0, 1, 0,
- -sin(a), 0, cos(a));
- }
- mat3 getRotMat3Z(float a) {
- return mat3(cos(a), -sin(a), 0,
- sin(a), cos(a), 0,
- 0, 0, 1);
- }
- float length(vec2 v) {
- return sqrt(v.x ^^ 2 + v.y ^^ 2);
- }
- float length(vec3 v) {
- return sqrt(v.x ^^ 2 + v.y ^^ 2 + v.z ^^ 2);
- }
- vec2 normalize(vec2 v) {
- float len = length(v);
- return vec2(v.x/len, v.y/len);
- }
- vec3 normalize(vec3 v) {
- float len = length(v);
- return vec3(v.x/len, v.y/len, v.z/len);
- }
- struct HitInfo {
- float dist;
- vec3 color;
- }
- const vec3 circleColor = vec3(1., 0.5, 0.);
- const float circleRad = 0.5;
- const uint PIXEL_SIZE = 8;
- const float EPSILON = 0.001;
- const float MAX_DIST = 50;
- HitInfo sphere(vec3 r, float rad) {
- return HitInfo(length(r) - rad, vec3(0, 1, 0));
- }
- HitInfo box(vec3 r, vec3 s) {
- return HitInfo(fmax(fmax(abs(r.x) - s.x, abs(r.y) - s.y), abs(r.z) - s.z), vec3(1, 0, 0));
- }
- HitInfo map(vec3 r) {
- auto h1 = sphere(r, 1);
- auto h2 = box(r, vec3(0.8, 0.8, 0.8));
- float d;
- if(h1.dist < h2.dist) {
- return h1;
- }
- return h2;
- }
- void main() {
- DerelictSDL2.load();
- SDL_Window* window = SDL_CreateWindow("SDL2/OpenGL Demo", 200, 200, PIXEL_SIZE*128, PIXEL_SIZE*72, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
- SDL_Surface* surface = SDL_GetWindowSurface(window);
- SDL_GLContext glcontext = SDL_GL_CreateContext(window);
- SDL_Event event;
- auto quit = false;
- auto start = Clock.currTime;
- uint frames = 0;
- while (!quit) {
- auto time = (cast(float)(Clock.currTime - start).total!"nsecs")/1000000000;
- while(SDL_PollEvent(&event)) {
- if (event.type == SDL_QUIT) {
- writefln("%s", frames/time);
- quit = true;
- }
- }
- auto res = vec2(surface.w/PIXEL_SIZE, surface.h/PIXEL_SIZE);
- for(auto x = 0; x < surface.w/PIXEL_SIZE; x++) {
- for(auto y = 0; y < surface.h/PIXEL_SIZE; y++) {
- auto coord = vec2(x, y);
- auto color = pixel(coord, res, time);
- ubyte r = cast(ubyte)(color.x * 255);
- ubyte g = cast(ubyte)(color.y * 255);
- ubyte b = cast(ubyte)(color.z * 255);
- SDL_Rect rect = SDL_Rect(x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
- SDL_FillRect(surface, &rect, r << 16 | g << 8 | b);
- }
- }
- frames++;
- SDL_UpdateWindowSurface(window);
- }
- }
- vec3 pixel(vec2 coord, vec2 res, float time) {
- vec2 uv = coord / res;
- uv.x *= res.x/res.y;
- uv.x -= res.x/res.y/2;
- uv.y -= 0.5;
- uv *= 2;
- // Rotation
- vec3 ro = vec3(0, 0, -2);
- ro = getRotMat3Y(time) * ro;
- ro = getRotMat3Z(time) * ro;
- ro = getRotMat3X(time) * ro;
- vec3 rd = normalize(vec3(uv.x, uv.y, 1));
- rd = getRotMat3Y(time) * rd;
- rd = getRotMat3Z(time) * rd;
- rd = getRotMat3X(time) * rd;
- // Raymarching
- float l = 0;
- for(uint i = 0; i < 100; i++) {
- vec3 r = ro + rd * l;
- auto hit = map(r);
- if(hit.dist <= EPSILON) {
- return hit.color;
- }
- if(l > MAX_DIST) {
- return vec3(0, 0, 0);
- }
- l = l + hit.dist;
- }
- return vec3(0, 0, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement