Skip to content

Instantly share code, notes, and snippets.

@abhi-jha
Forked from Wunkolo/compact.cpp
Created January 21, 2019 01:56
Show Gist options
  • Select an option

  • Save abhi-jha/46efcb25ad2effcb1ce9d5f68c028eda to your computer and use it in GitHub Desktop.

Select an option

Save abhi-jha/46efcb25ad2effcb1ce9d5f68c028eda to your computer and use it in GitHub Desktop.

Revisions

  1. @Wunkolo Wunkolo revised this gist Jan 21, 2019. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,7 @@
    ![](http://i.imgur.com/10u84LS.gif)
    ![](http://i.imgur.com/Zu8cuz4.gif)
    ![](http://i.imgur.com/xYeeKtu.gif)
    [More here!](https://github.com/Wunkolo/MarchASCII)

    # [More here!](https://github.com/Wunkolo/MarchASCII)

    ![](https://camo.githubusercontent.com/70db6cfbc78b340440559cb0d5d9235d7a706f8c/68747470733a2f2f692e696d6775722e636f6d2f723935613972492e676966)
  2. @Wunkolo Wunkolo revised this gist Jan 21, 2019. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    ![](http://i.imgur.com/10u84LS.gif)
    ![](http://i.imgur.com/Zu8cuz4.gif)
    ![](http://i.imgur.com/xYeeKtu.gif)
    ![](http://i.imgur.com/xYeeKtu.gif)
    [More here!](https://github.com/Wunkolo/MarchASCII)
    ![](https://camo.githubusercontent.com/70db6cfbc78b340440559cb0d5d9235d7a706f8c/68747470733a2f2f692e696d6775722e636f6d2f723935613972492e676966)
  3. @Wunkolo Wunkolo revised this gist Jan 21, 2019. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions compact.cpp
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #include <math.h>
    #include <algorithm>
    #include <string>
    #include <pmmintrin.h>
    #include <immintrin.h>
    using namespace std;typedef float R;
    #define _W 79
    #define _H 39
    @@ -10,4 +10,4 @@ using namespace std;typedef float R;
    #define C const
    #define E return
    #define PQ M*(3.1415f/180)
    union J{__m128 V;J(__m128 V):V(V){}J(R X,R Y,R Z):X(X),Y(Y),Z(Z){}struct{R X,Y,Z;};R L()C{E _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(V,V,0x71)));}J N()C{E _mm_mul_ps(V,_mm_rsqrt_ps(_mm_dp_ps(V,V,0x7f)));}R D(C J& O)C{E _mm_cvtss_f32(_mm_dp_ps(V,O.V,0x71));}J A()C{E J{abs(X),abs(Y),abs(Z)};}J OP+(C J& O)C{E _mm_add_ps(V,O.V);}J OP-(C J& O)C{E _mm_sub_ps(V,O.V);}J OP*(C J& O)C{E _mm_mul_ps(V,O.V);}J OP/(C J& O)C{E _mm_div_ps(V,O.V);}J OP+(C R& O)C{E _mm_add_ps(V,_mm_set1_ps(O));}J OP-(C R& O)C{E _mm_sub_ps(V,_mm_set1_ps(O));}J OP*(C R& O)C{E J{_mm_mul_ps(V,_mm_set1_ps(O))};}};R BX(C J& P,J B){J D=P.A()-B;E min(max(D.X,max(D.Y, D.Z)),.0f)+J{max(D.X,.0f),max(D.Y,.0f),max(D.Z,0.0f)}.L();}R RB(C J& P,J B,R R){E BX(P,B)-R;}J RY(C J& P,R A){E J{P.Z*sin(A)+P.X*cos(A),P.Y,P.Z*cos(A)-P.X*sin(A),};}J RZ(C J& P,R A){E J{P.X*cos(A)-P.Y*sin(A),P.X*sin(A)+P.Y*cos(A),P.Z,};}static size_t M=0;R Q(C J& P){R D=P.Y+2;D=min(D,RB(RY(RZ(P,PQ),PQ),J{2,2,2},0.5f));E D;}J Nor(C J& P){E J{Q(P+J{EP,0,0})-Q(P-J{EP,0,0}),Q(P+J{0,EP,0})-Q(P-J{0,EP,0}),Q(P+J{0,0,EP})-Q(P-J{0,0,EP}),}.N();}R Y(C J& O,C J& D,bool* H){R T=0;for(size_t i=0;i<128;i++){R Y=Q(O+(D*T));if(Y<EP){*H=1;break;}T+=Y;}E T;}R B(C J& O,C J& D,R U,R I,R K){R S=1;for(R t=U;t<I;){R di=Q(O+D*t);if(di<EP){E 0;}S=min(S,K*di/t);t+=di;}E S;}int main(){J LD=J{0.5,1,0.25}.N();J G=J{0,1,-8};string S;S.reserve(_W*_H);do{M++;for(size_t y=0;y<_H;y++){for(size_t x=0;x<_W;x++){J K(x,y,1);K=K/J(_W,_H,1);K=(K*2.0)-1;K.Y=-K.Y;K.X*=_W/_H;K.Z=R(1/0.726);K=K.N();bool H=0;R Z=Y(G,K,&H);J P=G+(K*Z);if(H){J N=Nor(P);R D=N.D(LD);D*=0.5;D+=0.5;D*=D;D*=B(P,LD,R(0.5),10,10);S+=".:*oe$&#%@"[static_cast<size_t>(D*10)];}else{S+=' ';}}S+="\n";}printf("%s",S.c_str());S.clear();}while(M<360);E 0;}
    union J{__m128 V;J(__m128 V):V(V){}J(R X,R Y,R Z):X(X),Y(Y),Z(Z){}struct{R X,Y,Z;};R L()C{E _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(V,V,0x71)));}J N()C{E _mm_mul_ps(V,_mm_rsqrt_ps(_mm_dp_ps(V,V,0x7f)));}R D(C J& O)C{E _mm_cvtss_f32(_mm_dp_ps(V,O.V,0x71));}J A()C{E J{abs(X),abs(Y),abs(Z)};}J OP+(C J& O)C{E _mm_add_ps(V,O.V);}J OP-(C J& O)C{E _mm_sub_ps(V,O.V);}J OP*(C J& O)C{E _mm_mul_ps(V,O.V);}J OP/(C J& O)C{E _mm_div_ps(V,O.V);}J OP+(C R& O)C{E _mm_add_ps(V,_mm_set1_ps(O));}J OP-(C R& O)C{E _mm_sub_ps(V,_mm_set1_ps(O));}J OP*(C R& O)C{E J{_mm_mul_ps(V,_mm_set1_ps(O))};}};R BX(C J& P,J B){J D=P.A()-B;E min(max(D.X,max(D.Y, D.Z)),.0f)+J{max(D.X,.0f),max(D.Y,.0f),max(D.Z,0.0f)}.L();}R RB(C J& P,J B,R R){E BX(P,B)-R;}J RY(C J& P,R A){E J{P.Z*sin(A)+P.X*cos(A),P.Y,P.Z*cos(A)-P.X*sin(A),};}J RZ(C J& P,R A){E J{P.X*cos(A)-P.Y*sin(A),P.X*sin(A)+P.Y*cos(A),P.Z,};}static size_t M=0;R Q(C J& P){R D=P.Y+2;D=min(D,RB(RY(RZ(P,PQ),PQ),J{2,2,2},0.5f));E D;}J Nor(C J& P){E J{Q(P+J{EP,0,0})-Q(P-J{EP,0,0}),Q(P+J{0,EP,0})-Q(P-J{0,EP,0}),Q(P+J{0,0,EP})-Q(P-J{0,0,EP}),}.N();}R Y(C J& O,C J& D,bool* H){R T=0;for(size_t i=0;i<128;i++){R Y=Q(O+(D*T));if(Y<EP){*H=1;break;}T+=Y;}E T;}R B(C J& O,C J& D,R U,R I,R K){R S=1;for(R t=U;t<I;){R di=Q(O+D*t);if(di<EP){E 0;}S=min(S,K*di/t);t+=di;}E S;}int main(){J LD=J{0.5,1,0.25}.N();J G=J{0,1,-8};string S;S.reserve(_W*_H);do{M++;for(size_t y=0;y<_H;y++){for(size_t x=0;x<_W;x++){J K(x,y,1);K=K/J(_W,_H,1);K=(K*2.0)-1;K.Y=-K.Y;K.X*=_W/_H;K.Z=R(1/0.726);K=K.N();bool H=0;R Z=Y(G,K,&H);J P=G+(K*Z);if(H){J N=Nor(P);R D=N.D(LD);D*=0.5;D+=0.5;D*=D;D*=B(P,LD,R(0.5),10,10);S+=".:*oe$&#%@"[static_cast<size_t>(D*10)];}else{S+=' ';}}S+="\n";}printf("%s",S.c_str());S.clear();}while(M<360);E 0;}
  4. @Wunkolo Wunkolo revised this gist Dec 10, 2017. No changes.
  5. @Wunkolo Wunkolo revised this gist Dec 30, 2015. 1 changed file with 23 additions and 24 deletions.
    47 changes: 23 additions & 24 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -336,27 +336,36 @@ Real Capsule(const Vec3& Position, Vec3 A, Vec3 B, Real Radius)
    }
    Real Torus(const Vec3& Position, Real InRadius, Real OutRadius)
    {
    Vec3 Q{ Vec3{Position.X,Position.Z,0}.Length() - OutRadius,Position.Y,0 };
    Vec3 Q{ Vec3{ Position.X,Position.Z,0 }.Length() - OutRadius,Position.Y,0 };
    return Q.Length() - InRadius;
    }
    }

    namespace Operations
    {
    Real Clamp(Real A, Real Min, Real Max)
    {
    const Real T = A < Min ? Min : A;
    return T > Max ? Max : T;
    }
    Real Lerp(Real A, Real B, Real T)
    {
    return std::fma(T, B, std::fma(-T, A, A));
    }
    Real Union(Real A, Real B)
    {
    return std::min(A, B);
    }
    Real SmoothUnion(Real A, Real B, Real K = 8)
    Real SmoothUnion(Real A, Real B, Real K = 1)
    {
    /*
    Power Smooth
    A = std::pow(A, K);
    B = std::pow(B, K);
    return std::pow((A*B) / (A + B), Real(1) / K);
    */
    Real H = std::min<Real>(0, std::max<Real>(1, Real(0.5) + Real(0.5)*(B - A) / K));
    return (B * (Real(1.0) - H) + A*H) - (K*H*(Real(1.0) - H));
    Real H = Clamp(Real(0.5) + Real(0.5)*(B - A) / K, 0, 1);
    return Lerp(B, A, H) - (K*H*(Real(1.0) - H));
    }
    Real Intersection(Real A, Real B)
    {
    @@ -424,15 +433,6 @@ Real Scene(const Vec3& Point)

    Distance = Shapes::Plane(Point, Vec3{ 0,1,0 });

    Distance = Operations::Union(
    Distance,
    Shapes::Sphere(
    Translate::RepeatGround(
    Point,
    Vec3{ 10,0,10 }),
    1)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::RoundBox(
    @@ -450,24 +450,24 @@ Real Scene(const Vec3& Point)
    Real(3.75)
    ));

    Distance = Operations::Union(
    Distance = Operations::SmoothUnion(
    Distance,
    Shapes::Torus(
    Translate::RotX(Point - Vec3{ 0,Real(0.5),12 }, 45),
    Real(1), Real(6)
    )
    Real(0.5), Real(7)
    ), 3
    );

    for( size_t i = 1; i < 20; i++ )
    for( size_t i = 1; i < 5; i++ )
    {
    Distance = Operations::Union(
    Distance = Operations::SmoothUnion(
    Distance,
    Shapes::Torus(
    Translate::RotZ(
    Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), Real(i * 30 + (Tick * 5))
    ),
    Real(1), Real(6)
    ));
    ), 3);
    }

    return Distance;
    @@ -477,7 +477,7 @@ Vec3 CalcNormal(const Vec3& Point)
    {
    #define EPSILON static_cast<Real>(0.001)
    return Vec3{
    Scene(Point + Vec3{ EPSILON,0,0}) - Scene(Point - Vec3{ EPSILON,0,0 }),
    Scene(Point + Vec3{ EPSILON,0,0 }) - Scene(Point - Vec3{ EPSILON,0,0 }),
    Scene(Point + Vec3{ 0,EPSILON,0 }) - Scene(Point - Vec3{ 0,EPSILON,0 }),
    Scene(Point + Vec3{ 0,0,EPSILON }) - Scene(Point - Vec3{ 0,0,EPSILON }),
    }.Normalized();
    @@ -519,19 +519,18 @@ Real Shadow(const Vec3& LightPos, const Vec3& LightDir, Real Min, Real Max, Real
    return Res;
    }

    const char Shades[] = ".:*oe$&#%@";
    const char Shades[] = ".:*oe&#%@";

    int main()
    {
    Vec3 LightDir = Vec3{ 1,0,Real(-0.15) }.Normalized();
    Vec3 LightDir = Vec3{ 1,1,1 }.Normalized();
    Vec3 EyePos = Vec3{ 0,2,-6 };

    std::string Screen;
    Screen.reserve(WIDTH * HEIGHT);
    do
    {
    EyePos.Z += Real(1);
    LightDir = Translate::RotZ(LightDir, Real(0.45));
    EyePos.Z += Real(0.25);
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
  6. @Wunkolo Wunkolo revised this gist Dec 30, 2015. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    ![](http://i.imgur.com/10u84LS.gif)
    ![](http://i.imgur.com/Zu8cuz4.gif)
    ![](http://i.imgur.com/xYeeKtu.gif)
  7. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions compact.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    #include <math.h>
    #include <algorithm>
    #include <string>
    #include <pmmintrin.h>
    using namespace std;typedef float R;
    #define _W 79
    #define _H 39
    #define EP 0.01f
    #define OP operator
    #define C const
    #define E return
    #define PQ M*(3.1415f/180)
    union J{__m128 V;J(__m128 V):V(V){}J(R X,R Y,R Z):X(X),Y(Y),Z(Z){}struct{R X,Y,Z;};R L()C{E _mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(V,V,0x71)));}J N()C{E _mm_mul_ps(V,_mm_rsqrt_ps(_mm_dp_ps(V,V,0x7f)));}R D(C J& O)C{E _mm_cvtss_f32(_mm_dp_ps(V,O.V,0x71));}J A()C{E J{abs(X),abs(Y),abs(Z)};}J OP+(C J& O)C{E _mm_add_ps(V,O.V);}J OP-(C J& O)C{E _mm_sub_ps(V,O.V);}J OP*(C J& O)C{E _mm_mul_ps(V,O.V);}J OP/(C J& O)C{E _mm_div_ps(V,O.V);}J OP+(C R& O)C{E _mm_add_ps(V,_mm_set1_ps(O));}J OP-(C R& O)C{E _mm_sub_ps(V,_mm_set1_ps(O));}J OP*(C R& O)C{E J{_mm_mul_ps(V,_mm_set1_ps(O))};}};R BX(C J& P,J B){J D=P.A()-B;E min(max(D.X,max(D.Y, D.Z)),.0f)+J{max(D.X,.0f),max(D.Y,.0f),max(D.Z,0.0f)}.L();}R RB(C J& P,J B,R R){E BX(P,B)-R;}J RY(C J& P,R A){E J{P.Z*sin(A)+P.X*cos(A),P.Y,P.Z*cos(A)-P.X*sin(A),};}J RZ(C J& P,R A){E J{P.X*cos(A)-P.Y*sin(A),P.X*sin(A)+P.Y*cos(A),P.Z,};}static size_t M=0;R Q(C J& P){R D=P.Y+2;D=min(D,RB(RY(RZ(P,PQ),PQ),J{2,2,2},0.5f));E D;}J Nor(C J& P){E J{Q(P+J{EP,0,0})-Q(P-J{EP,0,0}),Q(P+J{0,EP,0})-Q(P-J{0,EP,0}),Q(P+J{0,0,EP})-Q(P-J{0,0,EP}),}.N();}R Y(C J& O,C J& D,bool* H){R T=0;for(size_t i=0;i<128;i++){R Y=Q(O+(D*T));if(Y<EP){*H=1;break;}T+=Y;}E T;}R B(C J& O,C J& D,R U,R I,R K){R S=1;for(R t=U;t<I;){R di=Q(O+D*t);if(di<EP){E 0;}S=min(S,K*di/t);t+=di;}E S;}int main(){J LD=J{0.5,1,0.25}.N();J G=J{0,1,-8};string S;S.reserve(_W*_H);do{M++;for(size_t y=0;y<_H;y++){for(size_t x=0;x<_W;x++){J K(x,y,1);K=K/J(_W,_H,1);K=(K*2.0)-1;K.Y=-K.Y;K.X*=_W/_H;K.Z=R(1/0.726);K=K.N();bool H=0;R Z=Y(G,K,&H);J P=G+(K*Z);if(H){J N=Nor(P);R D=N.D(LD);D*=0.5;D+=0.5;D*=D;D*=B(P,LD,R(0.5),10,10);S+=".:*oe$&#%@"[static_cast<size_t>(D*10)];}else{S+=' ';}}S+="\n";}printf("%s",S.c_str());S.clear();}while(M<360);E 0;}
  8. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 50 additions and 58 deletions.
    108 changes: 50 additions & 58 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -8,57 +8,57 @@
    #define NOMINMAX
    #include <Windows.h>
    #include <fstream>
    void CaptureScreen(HWND window, const char* filename)
    void CaptureScreen(HWND Window, const char* filename)
    {
    RECT windowRect;
    GetWindowRect(window, &windowRect);

    int bitmap_dx = windowRect.right - windowRect.left;
    int bitmap_dy = windowRect.bottom - windowRect.top;

    std::ofstream file(filename, std::ios::binary);
    if( !file ) return;

    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;

    fileHeader.bfType = 0x4d42;
    fileHeader.bfSize = 0;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    infoHeader.biSize = sizeof(infoHeader);
    infoHeader.biWidth = bitmap_dx;
    infoHeader.biHeight = bitmap_dy;
    infoHeader.biPlanes = 1;
    infoHeader.biBitCount = 24;
    infoHeader.biCompression = BI_RGB;
    infoHeader.biSizeImage = 0;
    infoHeader.biXPelsPerMeter = 0;
    infoHeader.biYPelsPerMeter = 0;
    infoHeader.biClrUsed = 0;
    infoHeader.biClrImportant = 0;

    file.write((char*)&fileHeader, sizeof(fileHeader));
    file.write((char*)&infoHeader, sizeof(infoHeader));

    BITMAPINFO info;
    info.bmiHeader = infoHeader;

    HDC winDC = GetWindowDC(window);
    RECT WindowBounds;
    GetWindowRect(Window, &WindowBounds);

    int Width = WindowBounds.right - WindowBounds.left;
    int Height = WindowBounds.bottom - WindowBounds.top;

    std::ofstream fOut(filename, std::ios::binary);
    if( !fOut ) return;

    BITMAPFILEHEADER BmpHeader;
    BITMAPINFOHEADER InfoHeader;

    BmpHeader.bfType = 0x4d42;
    BmpHeader.bfSize = 0;
    BmpHeader.bfReserved1 = 0;
    BmpHeader.bfReserved2 = 0;
    BmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    InfoHeader.biSize = sizeof(InfoHeader);
    InfoHeader.biWidth = Width;
    InfoHeader.biHeight = Height;
    InfoHeader.biPlanes = 1;
    InfoHeader.biBitCount = 24;
    InfoHeader.biCompression = BI_RGB;
    InfoHeader.biSizeImage = 0;
    InfoHeader.biXPelsPerMeter = 0;
    InfoHeader.biYPelsPerMeter = 0;
    InfoHeader.biClrUsed = 0;
    InfoHeader.biClrImportant = 0;

    fOut.write((char*)&BmpHeader, sizeof(BmpHeader));
    fOut.write((char*)&InfoHeader, sizeof(InfoHeader));

    BITMAPINFO BmpInfo;
    BmpInfo.bmiHeader = InfoHeader;

    HDC winDC = GetWindowDC(Window);
    HDC memDC = CreateCompatibleDC(winDC);
    BYTE* memory = 0;
    HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
    SelectObject(memDC, bitmap);
    BitBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, 0, SRCCOPY);
    BYTE* Buffer = 0;
    HBITMAP ImageDC = CreateDIBSection(winDC, &BmpInfo, DIB_RGB_COLORS, (void**)&Buffer, 0, 0);
    SelectObject(memDC, ImageDC);
    BitBlt(memDC, 0, 0, Width, Height, winDC, 0, 0, SRCCOPY);
    DeleteDC(memDC);
    ReleaseDC(window, winDC);
    ReleaseDC(Window, winDC);

    int bytes = (((24 * bitmap_dx + 31) & (~31)) / 8)*bitmap_dy;
    file.write((const char*)memory, bytes);
    size_t Size = (((24 * Width + 31) & (~31)) / 8)*Height;
    fOut.write((const char*)Buffer, Size);

    DeleteObject(bitmap);
    DeleteObject(ImageDC);
    }

    #endif
    @@ -531,8 +531,8 @@ int main()
    do
    {
    EyePos.Z += Real(1);
    LightDir = Translate::RotZ(LightDir, 0.45)
    Tick++;
    LightDir = Translate::RotZ(LightDir, Real(0.45));
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    for( size_t x = 0; x < WIDTH; x++ )
    @@ -582,14 +582,7 @@ int main()

    Diffuse *= Shadow(Point, LightDir, Real(0.5), 10, 10);

    if( std::isfinite(Diffuse) )
    {
    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    }
    else
    {
    Screen += '!';
    }
    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    }
    else
    {
    @@ -599,11 +592,10 @@ int main()
    Screen += "\n";
    }
    printf("%s", Screen.c_str());
    // Screenshot
    #ifdef _WIN32
    //CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    #endif
    Screen.clear();
    } while( /*getchar() != 'q'*/ Tick < 300 );
    } while( Tick < 300 );
    return 0;
    }
  9. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -531,8 +531,8 @@ int main()
    do
    {
    EyePos.Z += Real(1);
    LightDir = Translate::RotZ(LightDir, 0.45).Normalized();
    Tick++;
    LightDir = Translate::RotZ(LightDir, 0.45)
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    for( size_t x = 0; x < WIDTH; x++ )
  10. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion main.cpp
    Original file line number Diff line number Diff line change
    @@ -601,7 +601,7 @@ int main()
    printf("%s", Screen.c_str());
    // Screenshot
    #ifdef _WIN32
    CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    //CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    #endif
    Screen.clear();
    } while( /*getchar() != 'q'*/ Tick < 300 );
  11. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 96 additions and 43 deletions.
    139 changes: 96 additions & 43 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -69,15 +69,15 @@ typedef float Real;

    #ifdef USE_SSE
    #include <pmmintrin.h>
    // simd modulo
    inline __m128 _mm_mod_ps2(const __m128& a, const __m128& aDiv)
    // Simd Modulo
    inline __m128 _mm_mod_ps2(const __m128& A, const __m128& Divisor)
    {
    __m128 c = _mm_div_ps(a, aDiv);
    __m128i i = _mm_cvttps_epi32(c);
    __m128 cTrunc = _mm_cvtepi32_ps(i);
    __m128 base = _mm_mul_ps(cTrunc, aDiv);
    __m128 r = _mm_sub_ps(a, base);
    return r;
    __m128 C = _mm_div_ps(A, Divisor);
    __m128i I = _mm_cvttps_epi32(C);
    __m128 Trunc = _mm_cvtepi32_ps(I);
    __m128 Base = _mm_mul_ps(Trunc, Divisor);
    __m128 Remainder = _mm_sub_ps(A, Base);
    return Remainder;
    }
    #endif

    @@ -104,7 +104,13 @@ union Vec3
    Real Length() const
    {
    #ifdef USE_SSE
    return static_cast<Real>(_mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(SimdReals, SimdReals, 0x71))));
    return static_cast<Real>(
    _mm_cvtss_f32(
    _mm_sqrt_ss(
    _mm_dp_ps(SimdReals, SimdReals, 0x71)
    )
    )
    );
    #else
    return static_cast<Real>(
    sqrt(X*X + Y*Y + Z*Z)
    @@ -116,8 +122,9 @@ union Vec3
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(
    this->SimdReals, _mm_rsqrt_ps(
    _mm_dp_ps(
    this->SimdReals, this->SimdReals, 0x7f)))
    _mm_dp_ps(this->SimdReals, this->SimdReals, 0x7f)
    )
    )
    };
    #else
    const Real Len = Length();
    @@ -150,18 +157,23 @@ union Vec3
    Vec3 operator + (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_add_ps(SimdReals, Other.SimdReals) };
    return Vec3{
    _mm_add_ps(SimdReals, Other.SimdReals)
    };
    #else
    return Vec3{
    X + Other.X,
    Y + Other.Y,
    Z + Other.Z };
    Z + Other.Z
    };
    #endif
    }
    Vec3 operator - (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_sub_ps(SimdReals,Other.SimdReals) };
    return Vec3{
    _mm_sub_ps(SimdReals,Other.SimdReals)
    };
    #else
    return Vec3{
    X - Other.X,
    @@ -174,7 +186,9 @@ union Vec3
    Vec3 operator * (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(SimdReals,Other.SimdReals) };
    return Vec3{
    _mm_mul_ps(SimdReals,Other.SimdReals)
    };
    #else
    return Vec3{
    X * Other.X,
    @@ -187,7 +201,9 @@ union Vec3
    Vec3 operator / (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_div_ps(SimdReals,Other.SimdReals) };
    return Vec3{
    _mm_div_ps(SimdReals,Other.SimdReals)
    };
    #else
    return Vec3{
    X / Other.X,
    @@ -200,7 +216,9 @@ union Vec3
    Vec3 operator % (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mod_ps2(SimdReals,Other.SimdReals) };
    return Vec3{
    _mm_mod_ps2(SimdReals,Other.SimdReals)
    };
    #else
    return Vec3{
    fmod(X,Other.X),
    @@ -213,7 +231,9 @@ union Vec3
    Vec3 operator + (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_add_ps(SimdReals,_mm_set1_ps(Other)) };
    return Vec3{
    _mm_add_ps(SimdReals,_mm_set1_ps(Other))
    };
    #else
    return Vec3{
    X + Other,
    @@ -226,7 +246,9 @@ union Vec3
    Vec3 operator - (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_sub_ps(SimdReals,_mm_set1_ps(Other)) };
    return Vec3{
    _mm_sub_ps(SimdReals,_mm_set1_ps(Other))
    };
    #else
    return Vec3{
    X - Other,
    @@ -239,7 +261,9 @@ union Vec3
    Vec3 operator * (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(SimdReals,_mm_set1_ps(Other)) };
    return Vec3{
    _mm_mul_ps(SimdReals,_mm_set1_ps(Other))
    };
    #else
    return Vec3{
    X * Other,
    @@ -252,7 +276,9 @@ union Vec3
    Vec3 operator / (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_div_ps(SimdReals,_mm_set1_ps(Other)) };
    return Vec3{
    _mm_div_ps(SimdReals,_mm_set1_ps(Other))
    };
    #else
    return Vec3{
    X / Other,
    @@ -265,7 +291,9 @@ union Vec3
    Vec3 operator % (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mod_ps2(SimdReals,_mm_set1_ps(Other)) };
    return Vec3{
    _mm_mod_ps2(SimdReals,_mm_set1_ps(Other))
    };
    #else
    return Vec3{
    fmod(X,Other),
    @@ -281,7 +309,6 @@ namespace Shapes
    Real Plane(const Vec3& Position, const Vec3& Normal)
    {
    return Position.Dot(Normal.Normalized());
    //return Position.Y;
    }
    Real Sphere(const Vec3& Position, Real Radius)
    {
    @@ -371,6 +398,17 @@ Vec3 RotZ(const Vec3& Position, Real Angle)
    Position.Z,
    };
    }
    Vec3 Repeat(const Vec3& Position, const Vec3& Bounds)
    {
    return (Position % Bounds) - (Bounds*Real(0.5));
    }
    Vec3 RepeatGround(const Vec3& Position, const Vec3& Bounds)
    {
    Vec3 Rep{ Position };
    Rep.X = std::remainder(Rep.X, Bounds.X) - (Bounds.X * Real(0.5));
    Rep.Z = std::remainder(Rep.Z, Bounds.Z) - (Bounds.Z * Real(0.5));
    return Rep;
    }
    }

    #define WIDTH (79)
    @@ -388,13 +426,20 @@ Real Scene(const Vec3& Point)

    Distance = Operations::Union(
    Distance,
    Shapes::Sphere(Point, 1.0)
    Shapes::Sphere(
    Translate::RepeatGround(
    Point,
    Vec3{ 10,0,10 }),
    1)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::RoundBox(Translate::RotZ(Point - Vec3{ -5,2,5 }, Real(15 + Tick * 15)),
    Vec3{ 1,2,1 }, 0.525f)
    Shapes::RoundBox(
    Translate::RotZ(
    Point - Vec3{ -5,2,5 }, Real(15 + Tick * 15)
    ),
    Vec3{ 1,2,1 }, 0.525f)
    );

    Distance = Operations::Union(
    @@ -407,16 +452,20 @@ Real Scene(const Vec3& Point)

    Distance = Operations::Union(
    Distance,
    Shapes::Torus(Translate::RotX(Point - Vec3{ 0,Real(0.5),12 }, 45),
    Real(1), Real(6)
    ));
    Shapes::Torus(
    Translate::RotX(Point - Vec3{ 0,Real(0.5),12 }, 45),
    Real(1), Real(6)
    )
    );

    for( size_t i = 1; i < 8; i++ )
    for( size_t i = 1; i < 20; i++ )
    {
    Distance = Operations::Union(
    Distance,
    Shapes::Torus(
    Translate::RotZ(Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), Real(i * 30 + (Tick * 5))),
    Translate::RotZ(
    Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), Real(i * 30 + (Tick * 5))
    ),
    Real(1), Real(6)
    ));
    }
    @@ -470,21 +519,19 @@ Real Shadow(const Vec3& LightPos, const Vec3& LightDir, Real Min, Real Max, Real
    return Res;
    }

    const char Shades[] = ".:*oe&$#%@";

    #include <float.h>
    const char Shades[] = ".:*oe$&#%@";

    int main()
    {
    //_controlfp_s(nullptr, _EM_INEXACT, _MCW_EM);
    Vec3 LightDir = Vec3{ 1,1,0 }.Normalized();
    Vec3 LightDir = Vec3{ 1,0,Real(-0.15) }.Normalized();
    Vec3 EyePos = Vec3{ 0,2,-6 };

    std::string Screen;
    Screen.reserve(WIDTH * HEIGHT);
    do
    {
    EyePos.Z += Real(2);
    EyePos.Z += Real(1);
    LightDir = Translate::RotZ(LightDir, 0.45).Normalized();
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    @@ -509,14 +556,20 @@ int main()
    UV.X *= WIDTH / HEIGHT;
    //UV.X *= 0.75;

    // Fov
    UV.Z = Real(2);
    /* Fov
    15deg bisec = tan((pi/12)/2) = 30 degrees fov = 0.1316524975873958
    30deg bisec = tan((pi/6)/2) = 60 degrees fov = 0.26794919243112270
    36deg bisec = tan(((2pi)/5)/2) = 72 degrees fov = 0.7265425280053608858
    45dec bisec = tan((pi/2)/2) = 90 degrees fov = 1
    */
    UV.Z = Real(1 / 0.7265425280053608858);
    UV = UV.Normalized();

    bool Hit = false;

    Real Distance = March(EyePos, UV.Normalized(), &Hit);
    Real Distance = March(EyePos, UV, &Hit);

    Vec3 Point = EyePos + (UV.Normalized() * Distance);
    Vec3 Point = EyePos + (UV * Distance);

    if( Hit )
    {
    @@ -548,9 +601,9 @@ int main()
    printf("%s", Screen.c_str());
    // Screenshot
    #ifdef _WIN32
    //CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    #endif
    Screen.clear();
    } while( /*getchar() != 'q'*/ Tick < 200 );
    } while( /*getchar() != 'q'*/ Tick < 300 );
    return 0;
    }
  12. @Wunkolo Wunkolo revised this gist Dec 29, 2015. 1 changed file with 152 additions and 27 deletions.
    179 changes: 152 additions & 27 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,7 @@ void CaptureScreen(HWND window, const char* filename)
    {
    RECT windowRect;
    GetWindowRect(window, &windowRect);

    int bitmap_dx = windowRect.right - windowRect.left;
    int bitmap_dy = windowRect.bottom - windowRect.top;

    @@ -64,24 +65,77 @@ void CaptureScreen(HWND window, const char* filename)

    typedef float Real;

    struct Vec3
    #define USE_SSE

    #ifdef USE_SSE
    #include <pmmintrin.h>
    // simd modulo
    inline __m128 _mm_mod_ps2(const __m128& a, const __m128& aDiv)
    {
    __m128 c = _mm_div_ps(a, aDiv);
    __m128i i = _mm_cvttps_epi32(c);
    __m128 cTrunc = _mm_cvtepi32_ps(i);
    __m128 base = _mm_mul_ps(cTrunc, aDiv);
    __m128 r = _mm_sub_ps(a, base);
    return r;
    }
    #endif

    union Vec3
    {
    Real X, Y, Z;
    #ifdef USE_SSE
    __m128 SimdReals;
    Vec3(__m128 Vec)
    :
    SimdReals(Vec)
    {
    }
    #endif
    Vec3(Real X, Real Y, Real Z)
    :
    X(X), Y(Y), Z(Z)
    {
    }
    Real Reals[3];
    struct
    {
    Real X, Y, Z;
    };
    Real Length() const
    {
    #ifdef USE_SSE
    return static_cast<Real>(_mm_cvtss_f32(_mm_sqrt_ss(_mm_dp_ps(SimdReals, SimdReals, 0x71))));
    #else
    return static_cast<Real>(
    sqrt(X*X + Y*Y + Z*Z)
    );
    #endif
    }
    Vec3 Normalized() const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(
    this->SimdReals, _mm_rsqrt_ps(
    _mm_dp_ps(
    this->SimdReals, this->SimdReals, 0x7f)))
    };
    #else
    const Real Len = Length();
    return (*this) / Len;
    #endif
    }

    Real Dot(const Vec3& Other) const
    {
    #ifdef USE_SSE
    return static_cast<Real>(
    _mm_cvtss_f32(
    _mm_dp_ps(SimdReals, Other.SimdReals, 0x71)
    )
    );
    #else
    return X * Other.X + Y * Other.Y + Z * Other.Z;
    #endif
    }

    Vec3 Abs() const
    @@ -95,90 +149,139 @@ struct Vec3

    Vec3 operator + (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_add_ps(SimdReals, Other.SimdReals) };
    #else
    return Vec3{
    X + Other.X,
    Y + Other.Y,
    Z + Other.Z };
    #endif
    }
    Vec3 operator - (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_sub_ps(SimdReals,Other.SimdReals) };
    #else
    return Vec3{
    X - Other.X,
    Y - Other.Y,
    Z - Other.Z };
    Z - Other.Z
    };
    #endif
    }

    Vec3 operator * (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(SimdReals,Other.SimdReals) };
    #else
    return Vec3{
    X * Other.X,
    Y * Other.Y,
    Z * Other.Z };
    Z * Other.Z
    };
    #endif
    }

    Vec3 operator / (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_div_ps(SimdReals,Other.SimdReals) };
    #else
    return Vec3{
    X / Other.X,
    Y / Other.Y,
    Z / Other.Z };
    Z / Other.Z
    };
    #endif
    }

    Vec3 operator % (const Vec3& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mod_ps2(SimdReals,Other.SimdReals) };
    #else
    return Vec3{
    fmod(X,Other.X),
    fmod(Y,Other.Y),
    fmod(Z,Other.Z) };
    fmod(Z,Other.Z)
    };
    #endif
    }

    Vec3 operator + (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_add_ps(SimdReals,_mm_set1_ps(Other)) };
    #else
    return Vec3{
    X + Other,
    Y + Other,
    Z + Other };
    Z + Other
    };
    #endif
    }

    Vec3 operator - (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_sub_ps(SimdReals,_mm_set1_ps(Other)) };
    #else
    return Vec3{
    X - Other,
    Y - Other,
    Z - Other };
    Z - Other
    };
    #endif
    }

    Vec3 operator * (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mul_ps(SimdReals,_mm_set1_ps(Other)) };
    #else
    return Vec3{
    X * Other,
    Y * Other,
    Z * Other };
    Z * Other
    };
    #endif
    }

    Vec3 operator / (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_div_ps(SimdReals,_mm_set1_ps(Other)) };
    #else
    return Vec3{
    X / Other,
    Y / Other,
    Z / Other };
    Z / Other
    };
    #endif
    }

    Vec3 operator % (const Real& Other) const
    {
    #ifdef USE_SSE
    return Vec3{ _mm_mod_ps2(SimdReals,_mm_set1_ps(Other)) };
    #else
    return Vec3{
    fmod(X,Other),
    fmod(Y,Other),
    fmod(Z,Other) };
    fmod(Y , Other),
    fmod(Z , Other)
    };
    #endif
    }
    };

    namespace Shapes
    {
    Real Plane(const Vec3& Position, const Vec3& Normal)
    {
    //return Position.Dot(Normal.Normalized());
    return Position.Y;
    return Position.Dot(Normal.Normalized());
    //return Position.Y;
    }
    Real Sphere(const Vec3& Position, Real Radius)
    {
    @@ -206,7 +309,7 @@ Real Capsule(const Vec3& Position, Vec3 A, Vec3 B, Real Radius)
    }
    Real Torus(const Vec3& Position, Real InRadius, Real OutRadius)
    {
    Vec3 Q{ Vec3{Position.X,Position.Z,0}.Length() - OutRadius,Position.Y };
    Vec3 Q{ Vec3{Position.X,Position.Z,0}.Length() - OutRadius,Position.Y,0 };
    return Q.Length() - InRadius;
    }
    }
    @@ -217,6 +320,17 @@ Real Union(Real A, Real B)
    {
    return std::min(A, B);
    }
    Real SmoothUnion(Real A, Real B, Real K = 8)
    {
    /*
    Power Smooth
    A = std::pow(A, K);
    B = std::pow(B, K);
    return std::pow((A*B) / (A + B), Real(1) / K);
    */
    Real H = std::min<Real>(0, std::max<Real>(1, Real(0.5) + Real(0.5)*(B - A) / K));
    return (B * (Real(1.0) - H) + A*H) - (K*H*(Real(1.0) - H));
    }
    Real Intersection(Real A, Real B)
    {
    return std::max(A, B);
    @@ -259,16 +373,18 @@ Vec3 RotZ(const Vec3& Position, Real Angle)
    }
    }

    #define WIDTH 79
    #define HEIGHT 39
    #define WIDTH (79)
    #define HEIGHT (39)
    #define PREC 0.002

    static size_t Tick = 0;

    //// SCENE
    Real Scene(const Vec3& Point)
    {
    Real Distance = 0;

    Distance = Shapes::Plane(Point, Vec3{ 0,-1,0 });
    Distance = Shapes::Plane(Point, Vec3{ 0,1,0 });

    Distance = Operations::Union(
    Distance,
    @@ -300,7 +416,7 @@ Real Scene(const Vec3& Point)
    Distance = Operations::Union(
    Distance,
    Shapes::Torus(
    Translate::RotZ(Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), i * 30 + (Tick * 5)),
    Translate::RotZ(Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), Real(i * 30 + (Tick * 5))),
    Real(1), Real(6)
    ));
    }
    @@ -321,10 +437,9 @@ Vec3 CalcNormal(const Vec3& Point)
    Real March(const Vec3& Origin, const Vec3& Ray, bool* Hit)
    {
    Real Distance = 0;
    for( size_t i = 0; i < 64; i++ )
    for( size_t i = 0; i < 128; i++ )
    {
    Vec3 Point = Origin + Ray * Distance;
    Real ClosestSurface = Scene(Point);
    Real ClosestSurface = Scene(Origin + (Ray * Distance));
    if( ClosestSurface < PREC )
    {
    // "Hit" a surface
    @@ -334,7 +449,7 @@ Real March(const Vec3& Origin, const Vec3& Ray, bool* Hit)
    }
    break;
    }
    Distance += ClosestSurface;
    Distance += ClosestSurface * Real(0.75);
    }
    return Distance;
    }
    @@ -355,18 +470,21 @@ Real Shadow(const Vec3& LightPos, const Vec3& LightDir, Real Min, Real Max, Real
    return Res;
    }

    const char Shades[] = ".:*oe&#%@";
    const char Shades[] = ".:*oe&$#%@";

    #include <float.h>

    int main()
    {
    //_controlfp_s(nullptr, _EM_INEXACT, _MCW_EM);
    Vec3 LightDir = Vec3{ 1,1,0 }.Normalized();
    Vec3 EyePos = Vec3{ 0,2,-6 };

    std::string Screen;
    Screen.reserve(WIDTH * HEIGHT);
    do
    {
    EyePos.Z += Real(0.15);
    EyePos.Z += Real(2);
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    @@ -411,7 +529,14 @@ int main()

    Diffuse *= Shadow(Point, LightDir, Real(0.5), 10, 10);

    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    if( std::isfinite(Diffuse) )
    {
    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    }
    else
    {
    Screen += '!';
    }
    }
    else
    {
    @@ -423,7 +548,7 @@ int main()
    printf("%s", Screen.c_str());
    // Screenshot
    #ifdef _WIN32
    CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    //CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    #endif
    Screen.clear();
    } while( /*getchar() != 'q'*/ Tick < 200 );
  13. @Wunkolo Wunkolo revised this gist Dec 28, 2015. 1 changed file with 0 additions and 12 deletions.
    12 changes: 0 additions & 12 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -10,19 +10,14 @@
    #include <fstream>
    void CaptureScreen(HWND window, const char* filename)
    {
    // get screen rectangle
    RECT windowRect;
    GetWindowRect(window, &windowRect);

    // bitmap dimensions
    int bitmap_dx = windowRect.right - windowRect.left;
    int bitmap_dy = windowRect.bottom - windowRect.top;

    // create file
    std::ofstream file(filename, std::ios::binary);
    if( !file ) return;

    // save bitmap file headers
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;

    @@ -47,14 +42,9 @@ void CaptureScreen(HWND window, const char* filename)
    file.write((char*)&fileHeader, sizeof(fileHeader));
    file.write((char*)&infoHeader, sizeof(infoHeader));

    // dibsection information
    BITMAPINFO info;
    info.bmiHeader = infoHeader;

    // ------------------
    // THE IMPORTANT CODE
    // ------------------
    // create a dibsection and blit the window contents to the bitmap
    HDC winDC = GetWindowDC(window);
    HDC memDC = CreateCompatibleDC(winDC);
    BYTE* memory = 0;
    @@ -64,11 +54,9 @@ void CaptureScreen(HWND window, const char* filename)
    DeleteDC(memDC);
    ReleaseDC(window, winDC);

    // save dibsection data
    int bytes = (((24 * bitmap_dx + 31) & (~31)) / 8)*bitmap_dy;
    file.write((const char*)memory, bytes);

    // HA HA, forgot paste in the DeleteObject lol, happy now ;)?
    DeleteObject(bitmap);
    }

  14. @Wunkolo Wunkolo revised this gist Dec 28, 2015. 1 changed file with 157 additions and 27 deletions.
    184 changes: 157 additions & 27 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,76 @@
    #include <algorithm>
    #include <string>

    #ifdef _WIN32
    #define NOMINMAX
    #include <Windows.h>
    #include <fstream>
    void CaptureScreen(HWND window, const char* filename)
    {
    // get screen rectangle
    RECT windowRect;
    GetWindowRect(window, &windowRect);

    // bitmap dimensions
    int bitmap_dx = windowRect.right - windowRect.left;
    int bitmap_dy = windowRect.bottom - windowRect.top;

    // create file
    std::ofstream file(filename, std::ios::binary);
    if( !file ) return;

    // save bitmap file headers
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;

    fileHeader.bfType = 0x4d42;
    fileHeader.bfSize = 0;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    infoHeader.biSize = sizeof(infoHeader);
    infoHeader.biWidth = bitmap_dx;
    infoHeader.biHeight = bitmap_dy;
    infoHeader.biPlanes = 1;
    infoHeader.biBitCount = 24;
    infoHeader.biCompression = BI_RGB;
    infoHeader.biSizeImage = 0;
    infoHeader.biXPelsPerMeter = 0;
    infoHeader.biYPelsPerMeter = 0;
    infoHeader.biClrUsed = 0;
    infoHeader.biClrImportant = 0;

    file.write((char*)&fileHeader, sizeof(fileHeader));
    file.write((char*)&infoHeader, sizeof(infoHeader));

    // dibsection information
    BITMAPINFO info;
    info.bmiHeader = infoHeader;

    // ------------------
    // THE IMPORTANT CODE
    // ------------------
    // create a dibsection and blit the window contents to the bitmap
    HDC winDC = GetWindowDC(window);
    HDC memDC = CreateCompatibleDC(winDC);
    BYTE* memory = 0;
    HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
    SelectObject(memDC, bitmap);
    BitBlt(memDC, 0, 0, bitmap_dx, bitmap_dy, winDC, 0, 0, SRCCOPY);
    DeleteDC(memDC);
    ReleaseDC(window, winDC);

    // save dibsection data
    int bytes = (((24 * bitmap_dx + 31) & (~31)) / 8)*bitmap_dy;
    file.write((const char*)memory, bytes);

    // HA HA, forgot paste in the DeleteObject lol, happy now ;)?
    DeleteObject(bitmap);
    }

    #endif

    typedef float Real;

    struct Vec3
    @@ -117,36 +187,36 @@ struct Vec3

    namespace Shapes
    {
    Real Plane(Vec3 Position, Vec3 Normal)
    Real Plane(const Vec3& Position, const Vec3& Normal)
    {
    //return Position.Dot(Normal.Normalized());
    return Position.Y;
    }
    Real Sphere(Vec3 Position, Real Radius)
    Real Sphere(const Vec3& Position, Real Radius)
    {
    return Position.Length() - Radius;
    }
    Real Box(Vec3 Position, Vec3 Bounds)
    Real Box(const Vec3& Position, Vec3 Bounds)
    {
    Vec3 Dist = Position.Abs() - Bounds;
    return std::min<Real>(std::max(Dist.X, std::max<Real>(Dist.Y, Dist.Z)), 0.0) +
    Vec3{ std::max<Real>(Dist.X,0.0),
    std::max<Real>(Dist.Y,0.0),
    std::max<Real>(Dist.Z,0.0) }.Length();
    }
    Real RoundBox(Vec3 Position, Vec3 Bounds, Real Radius)
    Real RoundBox(const Vec3& Position, Vec3 Bounds, Real Radius)
    {
    return Box(Position, Bounds) - Radius;
    }
    Real Capsule(Vec3 Position, Vec3 A, Vec3 B, Real Radius)
    Real Capsule(const Vec3& Position, Vec3 A, Vec3 B, Real Radius)
    {
    Vec3 Pa = Position - A;
    Vec3 Ba = B - A;
    Real H = (Pa.Dot(Ba) / Ba.Dot(Ba));
    H = std::min<Real>(0, std::max<Real>(1.0, H));
    return (Pa - (Ba*H)).Length() - Radius;
    }
    Real Torus(Vec3 Position, Real InRadius, Real OutRadius)
    Real Torus(const Vec3& Position, Real InRadius, Real OutRadius)
    {
    Vec3 Q{ Vec3{Position.X,Position.Z,0}.Length() - OutRadius,Position.Y };
    return Q.Length() - InRadius;
    @@ -167,17 +237,46 @@ Real Subtract(Real A, Real B)
    {
    return Intersection(-A, B);
    }
    Vec3 Repeat(Vec3 Position, Vec3 Bounds)
    }

    namespace Translate
    {
    return (Position % Bounds) + (Bounds*Real(0.5));
    const static Real Pi(static_cast<Real>(3.1415926535897932384626433));
    Vec3 RotX(const Vec3& Position, Real Angle)
    {
    Angle *= Pi / Real(180);
    return Vec3{
    Position.X,
    Position.Y * cos(Angle) - Position.Z * sin(Angle),
    Position.Y * sin(Angle) + Position.Z * cos(Angle),
    };
    }
    Vec3 RotY(const Vec3& Position, Real Angle)
    {
    Angle *= Pi / Real(180);
    return Vec3{
    Position.Z * sin(Angle) + Position.X * cos(Angle),
    Position.Y,
    Position.Z * cos(Angle) - Position.X * sin(Angle),
    };
    }
    Vec3 RotZ(const Vec3& Position, Real Angle)
    {
    Angle *= Pi / Real(180);
    return Vec3{
    Position.X * cos(Angle) - Position.Y * sin(Angle),
    Position.X * sin(Angle) + Position.Y * cos(Angle),
    Position.Z,
    };
    }
    }

    #define WIDTH 79
    #define HEIGHT 37
    #define HEIGHT 39
    #define PREC 0.002

    Real Scene(Vec3 Point)
    static size_t Tick = 0;
    Real Scene(const Vec3& Point)
    {
    Real Distance = 0;

    @@ -190,13 +289,8 @@ Real Scene(Vec3 Point)

    Distance = Operations::Union(
    Distance,
    Shapes::Sphere(Operations::Repeat(Point, Vec3{ 1,1,1 }), 0.125)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::RoundBox(Point - Vec3{ -5,0,5 },
    Vec3{ 2,3.2f,0.2f }, 0.225f)
    Shapes::RoundBox(Translate::RotZ(Point - Vec3{ -5,2,5 }, Real(15 + Tick * 15)),
    Vec3{ 1,2,1 }, 0.525f)
    );

    Distance = Operations::Union(
    @@ -209,14 +303,24 @@ Real Scene(Vec3 Point)

    Distance = Operations::Union(
    Distance,
    Shapes::Torus(Point - Vec3{ 0,Real(0.5),12 },
    Real(0.5), Real(6)
    Shapes::Torus(Translate::RotX(Point - Vec3{ 0,Real(0.5),12 }, 45),
    Real(1), Real(6)
    ));

    for( size_t i = 1; i < 8; i++ )
    {
    Distance = Operations::Union(
    Distance,
    Shapes::Torus(
    Translate::RotZ(Translate::RotX(Point - Vec3{ 0,Real(0.5),Real(12 + i * 7) }, 85), i * 30 + (Tick * 5)),
    Real(1), Real(6)
    ));
    }

    return Distance;
    }

    Vec3 CalcNormal(Vec3 Point)
    Vec3 CalcNormal(const Vec3& Point)
    {
    #define EPSILON static_cast<Real>(0.001)
    return Vec3{
    @@ -226,7 +330,7 @@ Vec3 CalcNormal(Vec3 Point)
    }.Normalized();
    }

    Real March(Vec3 Origin, Vec3 Ray, bool* Hit)
    Real March(const Vec3& Origin, const Vec3& Ray, bool* Hit)
    {
    Real Distance = 0;
    for( size_t i = 0; i < 64; i++ )
    @@ -247,17 +351,35 @@ Real March(Vec3 Origin, Vec3 Ray, bool* Hit)
    return Distance;
    }

    Real Shadow(const Vec3& LightPos, const Vec3& LightDir, Real Min, Real Max, Real K)
    {
    Real Res = 1;
    for( Real t = Min; t < Max;)
    {
    Real Distance = Scene(LightPos + LightDir*t);
    if( Distance < PREC )
    {
    return 0.0;
    }
    Res = std::min(Res, K*Distance / t);
    t += Distance;
    }
    return Res;
    }

    const char Shades[] = ".:*oe&#%@";

    int main()
    {
    Vec3 LightDir = Vec3{ 1,1,0 }.Normalized();
    Vec3 EyePos = Vec3{ 0,2,-6 };

    std::string Screen;
    Screen.reserve(WIDTH * HEIGHT);
    do
    {
    EyePos.Z += 0.5;
    EyePos.Z += Real(0.15);
    Tick++;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    for( size_t x = 0; x < WIDTH; x++ )
    @@ -279,10 +401,10 @@ int main()

    // Aspect Ratio Correction
    UV.X *= WIDTH / HEIGHT;
    //UV.X *= 0.5;
    //UV.X *= 0.75;

    // Fov
    UV.Z = Real(0.7);
    UV.Z = Real(2);

    bool Hit = false;

    @@ -293,10 +415,14 @@ int main()
    if( Hit )
    {
    Vec3 Normal = CalcNormal(Point);
    Real Diffuse = Normal.Dot(Vec3{ Real(1),Real(1),Real(1) }.Normalized());
    Real Diffuse = Normal.Dot(LightDir);
    Diffuse *= 0.5;
    Diffuse += 0.5;

    Diffuse *= Diffuse;

    Diffuse *= Shadow(Point, LightDir, Real(0.5), 10, 10);

    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    }
    else
    @@ -306,8 +432,12 @@ int main()
    }
    Screen += "\n";
    }
    printf("%s\n", Screen.c_str());
    printf("%s", Screen.c_str());
    // Screenshot
    #ifdef _WIN32
    CaptureScreen(GetForegroundWindow(), (std::to_string(Tick) + ".bmp").c_str());
    #endif
    Screen.clear();
    } while( getchar() != 'q' );
    } while( /*getchar() != 'q'*/ Tick < 200 );
    return 0;
    }
  15. @Wunkolo Wunkolo created this gist Dec 28, 2015.
    313 changes: 313 additions & 0 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,313 @@
    #include <stdio.h>
    #include <stdint.h>
    #include <math.h>
    #include <algorithm>
    #include <string>

    typedef float Real;

    struct Vec3
    {
    Real X, Y, Z;
    Real Length() const
    {
    return static_cast<Real>(
    sqrt(X*X + Y*Y + Z*Z)
    );
    }
    Vec3 Normalized() const
    {
    const Real Len = Length();
    return (*this) / Len;
    }

    Real Dot(const Vec3& Other) const
    {
    return X * Other.X + Y * Other.Y + Z * Other.Z;
    }

    Vec3 Abs() const
    {
    return Vec3{
    abs(X),
    abs(Y),
    abs(Z)
    };
    }

    Vec3 operator + (const Vec3& Other) const
    {
    return Vec3{
    X + Other.X,
    Y + Other.Y,
    Z + Other.Z };
    }
    Vec3 operator - (const Vec3& Other) const
    {
    return Vec3{
    X - Other.X,
    Y - Other.Y,
    Z - Other.Z };
    }

    Vec3 operator * (const Vec3& Other) const
    {
    return Vec3{
    X * Other.X,
    Y * Other.Y,
    Z * Other.Z };
    }

    Vec3 operator / (const Vec3& Other) const
    {
    return Vec3{
    X / Other.X,
    Y / Other.Y,
    Z / Other.Z };
    }

    Vec3 operator % (const Vec3& Other) const
    {
    return Vec3{
    fmod(X,Other.X),
    fmod(Y,Other.Y),
    fmod(Z,Other.Z) };
    }

    Vec3 operator + (const Real& Other) const
    {
    return Vec3{
    X + Other,
    Y + Other,
    Z + Other };
    }

    Vec3 operator - (const Real& Other) const
    {
    return Vec3{
    X - Other,
    Y - Other,
    Z - Other };
    }

    Vec3 operator * (const Real& Other) const
    {
    return Vec3{
    X * Other,
    Y * Other,
    Z * Other };
    }

    Vec3 operator / (const Real& Other) const
    {
    return Vec3{
    X / Other,
    Y / Other,
    Z / Other };
    }

    Vec3 operator % (const Real& Other) const
    {
    return Vec3{
    fmod(X,Other),
    fmod(Y,Other),
    fmod(Z,Other) };
    }
    };

    namespace Shapes
    {
    Real Plane(Vec3 Position, Vec3 Normal)
    {
    //return Position.Dot(Normal.Normalized());
    return Position.Y;
    }
    Real Sphere(Vec3 Position, Real Radius)
    {
    return Position.Length() - Radius;
    }
    Real Box(Vec3 Position, Vec3 Bounds)
    {
    Vec3 Dist = Position.Abs() - Bounds;
    return std::min<Real>(std::max(Dist.X, std::max<Real>(Dist.Y, Dist.Z)), 0.0) +
    Vec3{ std::max<Real>(Dist.X,0.0),
    std::max<Real>(Dist.Y,0.0),
    std::max<Real>(Dist.Z,0.0) }.Length();
    }
    Real RoundBox(Vec3 Position, Vec3 Bounds, Real Radius)
    {
    return Box(Position, Bounds) - Radius;
    }
    Real Capsule(Vec3 Position, Vec3 A, Vec3 B, Real Radius)
    {
    Vec3 Pa = Position - A;
    Vec3 Ba = B - A;
    Real H = (Pa.Dot(Ba) / Ba.Dot(Ba));
    H = std::min<Real>(0, std::max<Real>(1.0, H));
    return (Pa - (Ba*H)).Length() - Radius;
    }
    Real Torus(Vec3 Position, Real InRadius, Real OutRadius)
    {
    Vec3 Q{ Vec3{Position.X,Position.Z,0}.Length() - OutRadius,Position.Y };
    return Q.Length() - InRadius;
    }
    }

    namespace Operations
    {
    Real Union(Real A, Real B)
    {
    return std::min(A, B);
    }
    Real Intersection(Real A, Real B)
    {
    return std::max(A, B);
    }
    Real Subtract(Real A, Real B)
    {
    return Intersection(-A, B);
    }
    Vec3 Repeat(Vec3 Position, Vec3 Bounds)
    {
    return (Position % Bounds) + (Bounds*Real(0.5));
    }
    }

    #define WIDTH 79
    #define HEIGHT 37
    #define PREC 0.002

    Real Scene(Vec3 Point)
    {
    Real Distance = 0;

    Distance = Shapes::Plane(Point, Vec3{ 0,-1,0 });

    Distance = Operations::Union(
    Distance,
    Shapes::Sphere(Point, 1.0)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::Sphere(Operations::Repeat(Point, Vec3{ 1,1,1 }), 0.125)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::RoundBox(Point - Vec3{ -5,0,5 },
    Vec3{ 2,3.2f,0.2f }, 0.225f)
    );

    Distance = Operations::Union(
    Distance,
    Shapes::Capsule(Point,
    Vec3{ 5,5,6 },
    Vec3{ -5,5,6 },
    Real(3.75)
    ));

    Distance = Operations::Union(
    Distance,
    Shapes::Torus(Point - Vec3{ 0,Real(0.5),12 },
    Real(0.5), Real(6)
    ));

    return Distance;
    }

    Vec3 CalcNormal(Vec3 Point)
    {
    #define EPSILON static_cast<Real>(0.001)
    return Vec3{
    Scene(Point + Vec3{ EPSILON,0,0}) - Scene(Point - Vec3{ EPSILON,0,0 }),
    Scene(Point + Vec3{ 0,EPSILON,0 }) - Scene(Point - Vec3{ 0,EPSILON,0 }),
    Scene(Point + Vec3{ 0,0,EPSILON }) - Scene(Point - Vec3{ 0,0,EPSILON }),
    }.Normalized();
    }

    Real March(Vec3 Origin, Vec3 Ray, bool* Hit)
    {
    Real Distance = 0;
    for( size_t i = 0; i < 64; i++ )
    {
    Vec3 Point = Origin + Ray * Distance;
    Real ClosestSurface = Scene(Point);
    if( ClosestSurface < PREC )
    {
    // "Hit" a surface
    if( Hit != nullptr )
    {
    *Hit = true;
    }
    break;
    }
    Distance += ClosestSurface;
    }
    return Distance;
    }

    const char Shades[] = ".:*oe&#%@";

    int main()
    {
    Vec3 EyePos = Vec3{ 0,2,-6 };

    std::string Screen;
    Screen.reserve(WIDTH * HEIGHT);
    do
    {
    EyePos.Z += 0.5;
    for( size_t y = 0; y < HEIGHT; y++ )
    {
    for( size_t x = 0; x < WIDTH; x++ )
    {
    Vec3 UV{
    static_cast<Real>(x),
    static_cast<Real>(y),
    1 };
    UV = UV / Vec3{
    WIDTH,
    HEIGHT,
    1 };

    // Recanonicalize [-1,1]
    UV = (UV * 2.0) - 1.0;

    // Flip Y axis
    UV.Y *= Real(-1);

    // Aspect Ratio Correction
    UV.X *= WIDTH / HEIGHT;
    //UV.X *= 0.5;

    // Fov
    UV.Z = Real(0.7);

    bool Hit = false;

    Real Distance = March(EyePos, UV.Normalized(), &Hit);

    Vec3 Point = EyePos + (UV.Normalized() * Distance);

    if( Hit )
    {
    Vec3 Normal = CalcNormal(Point);
    Real Diffuse = Normal.Dot(Vec3{ Real(1),Real(1),Real(1) }.Normalized());
    Diffuse *= 0.5;
    Diffuse += 0.5;

    Screen += Shades[static_cast<size_t>(Diffuse*(sizeof(Shades) - 2))];
    }
    else
    {
    Screen += ' ';
    }
    }
    Screen += "\n";
    }
    printf("%s\n", Screen.c_str());
    Screen.clear();
    } while( getchar() != 'q' );
    return 0;
    }