#pragma once #define FATALERROR(m) FatalError( __FILE__, __LINE__, m ) #define ERRORMESSAGE(m,c) FatalError( __FILE__, __LINE__, m, c ) #define CHECKCL(r) CheckCL( r, __FILE__, __LINE__ ) #define MALLOC64(x) ((x)==0?0:_aligned_malloc((x),64)) #define FREE64(x) _aligned_free(x) // threading #define MAXJOBS 128 #define MAXJOBTHREADS 128 // system includes #include #include #include "cuda.h" #include "cudaGL.h" #include #include #include #include #include #include #include #include #include #include "zlib.h" #include "xmmintrin.h" #include "emmintrin.h" // external libraries #include "freeimage.h" // namespaces using namespace std; typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned __int64 uint64; // vectors class float2 // adapted from https://github.com/dcow/RayTracer { public: union { struct { float x, y; }; float cell[2]; }; float2() {} float2( float v ) : x( v ), y( v ) {} float2( float x, float y ) : x( x ), y( y ) {} float2 operator - () const { return float2( -x, -y ); } float2 operator + ( const float2& addOperand ) const { return float2( x + addOperand.x, y + addOperand.y ); } float2 operator - ( const float2& operand ) const { return float2( x - operand.x, y - operand.y ); } float2 operator * ( const float2& operand ) const { return float2( x * operand.x, y * operand.y ); } float2 operator * ( float operand ) const { return float2( x * operand, y * operand ); } void operator -= ( const float2& a ) { x -= a.x; y -= a.y; } void operator += ( const float2& a ) { x += a.x; y += a.y; } void operator *= ( const float2& a ) { x *= a.x; y *= a.y; } void operator *= ( float a ) { x *= a; y *= a; } float& operator [] ( const int idx ) { return cell[idx]; } float length() { return sqrtf( x * x + y * y ); } float sqrLentgh() { return x * x + y * y; } float2 normalized() { float r = 1.0f / length(); return float2( x * r, y * r ); } void normalize() { float r = 1.0f / length(); x *= r; y *= r; } static float2 normalize( float2 v ) { return v.normalized(); } float dot( const float2& operand ) const { return x * operand.x + y * operand.y; } }; class float3 { public: union { struct { float x, y, z; }; float cell[3]; }; float3() {} float3( float v ) : x( v ), y( v ), z( v ) {} float3( float x, float y, float z ) : x( x ), y( y ), z( z ) {} float3 operator - () const { return float3( -x, -y, -z ); } float3 operator + ( const float3& addOperand ) const { return float3( x + addOperand.x, y + addOperand.y, z + addOperand.z ); } float3 operator - ( const float3& operand ) const { return float3( x - operand.x, y - operand.y, z - operand.z ); } float3 operator * ( const float3& operand ) const { return float3( x * operand.x, y * operand.y, z * operand.z ); } float3 operator / ( const float3& operand ) const { return float3( x / operand.x, y / operand.y, z / operand.z ); } void operator -= ( const float3& a ) { x -= a.x; y -= a.y; z -= a.z; } void operator += ( const float3& a ) { x += a.x; y += a.y; z += a.z; } void operator *= ( const float3& a ) { x *= a.x; y *= a.y; z *= a.z; } void operator *= ( const float a ) { x *= a; y *= a; z *= a; } void operator /= ( const float3& a ) { x /= a.x; y /= a.y; z /= a.z; } void operator /= ( const float a ) { x /= a; y /= a; z /= a; } float operator [] ( const uint& idx ) const { return cell[idx]; } float& operator [] ( const uint& idx ) { return cell[idx]; } float length() const { return sqrtf( x * x + y * y + z * z ); } float sqrLentgh() const { return x * x + y * y + z * z; } float acc() const { return fabs( x ) + fabs( y ) + fabs( z ); } float3 normalized() const { float r = 1.0f / length(); return float3( x * r, y * r, z * r ); } void normalize() { float r = 1.0f / length(); x *= r; y *= r; z *= r; } static float3 normalize( const float3 v ) { return v.normalized(); } float3 cross( const float3& operand ) const { return float3( y * operand.z - z * operand.y, z * operand.x - x * operand.z, x * operand.y - y * operand.x ); } float dot( const float3& operand ) const { return x * operand.x + y * operand.y + z * operand.z; } }; float3 normalize( const float3& v ); float length( const float3& v ); float length( const float2& v ); float3 cross( const float3& a, const float3& b ); float dot( const float3& a, const float3& b ); float3 lerp( const float3& start, const float3& end, const float percent ); float3 operator * ( const float& s, const float3& v ); float3 operator * ( const float3& v, const float& s ); class float4 { public: union { struct { float x, y, z, w; }; struct { float3 xyz; float w2; }; float cell[4]; __m128 xyzw; /* force __alignof() to 16 */ }; float4() {} float4( float v ) : x( v ), y( v ), z( v ), w( v ) {} float4( float x, float y, float z, float w ) : x( x ), y( y ), z( z ), w( w ) {} float4( float3 a, float b ) : x( a.x ), y( a.y ), z( a.z ), w( b ) {} float4( float2 a, float2 b ) : x( a.x ), y( a.y ), z( b.x ), w( b.y ) {} float4 operator - () const { return float4( -x, -y, -z, -w ); } float4 operator + ( const float4& addOperand ) const { return float4( x + addOperand.x, y + addOperand.y, z + addOperand.z, w + addOperand.w ); } float4 operator - ( const float4& operand ) const { return float4( x - operand.x, y - operand.y, z - operand.z, w - operand.w ); } float4 operator * ( const float4& operand ) const { return float4( x * operand.x, y * operand.y, z * operand.z, w * operand.w ); } float4 operator * ( float operand ) const { return float4( x * operand, y * operand, z * operand, w * operand ); } void operator -= ( const float4& a ) { x -= a.x; y -= a.y; z -= a.z; w -= a.w; } void operator += ( const float4& a ) { x += a.x; y += a.y; z += a.z; w += a.w; } void operator *= ( const float4& a ) { x *= a.x; y *= a.y; z *= a.z; w *= a.w; } void operator *= ( float a ) { x *= a; y *= a; z *= a; w *= a; } void operator /= ( const float4& a ) { x /= a.x; y /= a.y; z /= a.z; w /= a.w; } void operator /= ( const float a ) { x /= a; y /= a; z /= a; w /= a; } float operator [] ( const uint& idx ) const { return cell[idx]; } float& operator [] ( const uint& idx ) { return cell[idx]; } float length() { return sqrtf( x * x + y * y + z * z + w * w ); } float sqrLentgh() { return x * x + y * y + z * z + w * w; } float4 normalized() { float r = 1.0f / length(); return float4( x * r, y * r, z * r, w * r ); } void normalize() { float r = 1.0f / length(); x *= r; y *= r; z *= r; w *= r; } static float4 normalize( float4 v ) { return v.normalized(); } float dot( const float4& operand ) const { return x * operand.x + y * operand.y + z * operand.z + w * operand.w; } }; float length( const float4& v ); class uint4 { public: union { struct { uint x, y, z, w; }; uint cell[4]; __m128i cell4; }; uint4() {} uint4( int v ) : x( v ), y( v ), z( v ), w( v ) {} uint4( int x, int y, int z, int w ) : x( x ), y( y ), z( z ), w( w ) {} uint4 operator + ( const uint4& addOperand ) const { return uint4( x + addOperand.x, y + addOperand.y, z + addOperand.z, w + addOperand.w ); } uint4 operator - ( const uint4& operand ) const { return uint4( x - operand.x, y - operand.y, z - operand.z, w - operand.w ); } uint4 operator * ( const uint4& operand ) const { return uint4( x * operand.x, y * operand.y, z * operand.z, w * operand.w ); } uint4 operator * ( uint operand ) const { return uint4( x * operand, y * operand, z * operand, w * operand ); } void operator -= ( const uint4& a ) { x -= a.x; y -= a.y; z -= a.z; w -= a.w; } void operator += ( const uint4& a ) { x += a.x; y += a.y; z += a.z; w += a.w; } void operator *= ( const uint4& a ) { x *= a.x; y *= a.y; z *= a.z; w *= a.w; } void operator *= ( uint a ) { x *= a; y *= a; z *= a; w *= a; } uint& operator [] ( const int idx ) { return cell[idx]; } }; class uchar4 { public: union { struct { uchar x, y, z, w; }; uchar cell[4]; }; uchar4() {} uchar4( uchar v ) : x( v ), y( v ), z( v ), w( v ) {} uchar4( uchar x, uchar y, uchar z, uchar w ) : x( x ), y( y ), z( z ), w( w ) {} uchar4 operator + ( const uchar4& addOperand ) const { return uchar4( x + addOperand.x, y + addOperand.y, z + addOperand.z, w + addOperand.w ); } uchar4 operator - ( const uchar4& operand ) const { return uchar4( x - operand.x, y - operand.y, z - operand.z, w - operand.w ); } uchar4 operator * ( const uchar4& operand ) const { return uchar4( x * operand.x, y * operand.y, z * operand.z, w * operand.w ); } uchar4 operator * ( uchar operand ) const { return uchar4( x * operand, y * operand, z * operand, w * operand ); } void operator -= ( const uchar4& a ) { x -= a.x; y -= a.y; z -= a.z; w -= a.w; } void operator += ( const uchar4& a ) { x += a.x; y += a.y; z += a.z; w += a.w; } void operator *= ( const uchar4& a ) { x *= a.x; y *= a.y; z *= a.z; w *= a.w; } void operator *= ( uchar a ) { x *= a; y *= a; z *= a; w *= a; } uchar& operator [] ( const int idx ) { return cell[idx]; } }; class int4 { public: union { struct { int x, y, z, w; }; int cell[4]; __m128i cell4; }; int4() {} int4( int v ) : x( v ), y( v ), z( v ), w( v ) {} int4( int x, int y, int z, int w ) : x( x ), y( y ), z( z ), w( w ) {} int4 operator - () const { return int4( -x, -y, -z, -w ); } int4 operator + ( const int4& addOperand ) const { return int4( x + addOperand.x, y + addOperand.y, z + addOperand.z, w + addOperand.w ); } int4 operator - ( const int4& operand ) const { return int4( x - operand.x, y - operand.y, z - operand.z, w - operand.w ); } int4 operator * ( const int4& operand ) const { return int4( x * operand.x, y * operand.y, z * operand.z, w * operand.w ); } int4 operator * ( int operand ) const { return int4( x * operand, y * operand, z * operand, w * operand ); } void operator -= ( const int4& a ) { x -= a.x; y -= a.y; z -= a.z; w -= a.w; } void operator += ( const int4& a ) { x += a.x; y += a.y; z += a.z; w += a.w; } void operator *= ( const int4& a ) { x *= a.x; y *= a.y; z *= a.z; w *= a.w; } void operator *= ( int a ) { x *= a; y *= a; z *= a; w *= a; } int& operator [] ( const int idx ) { return cell[idx]; } }; class int3 { public: union { struct { int x, y, z; }; int cell[3]; }; int3() {} int3( int v ) : x( v ), y( v ), z( v ) {} int3( int x, int y, int z ) : x( x ), y( y ), z( z ) {} int3 operator - () const { return int3( -x, -y, -z ); } int3 operator + ( const int3& addOperand ) const { return int3( x + addOperand.x, y + addOperand.y, z + addOperand.z ); } int3 operator - ( const int3& operand ) const { return int3( x - operand.x, y - operand.y, z - operand.z ); } int3 operator * ( const int3& operand ) const { return int3( x * operand.x, y * operand.y, z * operand.z ); } int3 operator * ( int operand ) const { return int3( x * operand, y * operand, z * operand ); } void operator -= ( const int3& a ) { x -= a.x; y -= a.y; z -= a.z; } void operator += ( const int3& a ) { x += a.x; y += a.y; z += a.z; } void operator *= ( const int3& a ) { x *= a.x; y *= a.y; z *= a.z; } void operator *= ( int a ) { x *= a; y *= a; z *= a; } int& operator [] ( const int idx ) { return cell[idx]; } }; class int2 { public: union { struct { int x, y; }; int cell[2]; __int64 xy; }; int2() {} int2( int v ) : x( v ), y( v ) {} int2( int x, int y ) : x( x ), y( y ) {} int2 operator - () const { return int2( -x, -y ); } int2 operator + ( const int2& addOperand ) const { return int2( x + addOperand.x, y + addOperand.y ); } int2 operator - ( const int2& operand ) const { return int2( x - operand.x, y - operand.y ); } int2 operator * ( const int2& operand ) const { return int2( x * operand.x, y * operand.y ); } int2 operator * ( int operand ) const { return int2( x * operand, y * operand ); } void operator -= ( const int2& a ) { x -= a.x; y -= a.y; } void operator += ( const int2& a ) { x += a.x; y += a.y; } void operator *= ( const int2& a ) { x *= a.x; y *= a.y; } void operator *= ( int a ) { x *= a; y *= a; } int& operator [] ( const int idx ) { return cell[idx]; } }; class mat4 { public: float cell[16]; float& operator [] ( const int idx ) { return cell[idx]; } float3 GetTranslation() { return float3( cell[3], cell[7], cell[11] ); } static mat4 Identity() { mat4 r; memset( r.cell, 0, 64 ); r.cell[0] = r.cell[5] = r.cell[10] = r.cell[15] = 1.0f; return r; } static mat4 RotateX( const float a ) { mat4 r = mat4::Identity(); r.cell[5] = cosf( a ); r.cell[6] = -sinf( a ); r.cell[9] = sinf( a ); r.cell[10] = cosf( a ); return r; }; static mat4 RotateY( const float a ) { mat4 r = mat4::Identity(); r.cell[0] = cosf( a ); r.cell[2] = sinf( a ); r.cell[8] = -sinf( a ); r.cell[10] = cosf( a ); return r; }; static mat4 RotateZ( const float a ) { mat4 r = mat4::Identity(); r.cell[0] = cosf( a ); r.cell[1] = -sinf( a ); r.cell[4] = sinf( a ); r.cell[5] = cosf( a ); return r; }; static mat4 Rotate( const float3& u, float a ) { const float c = cosf( a ), l_c = 1 - c, s = sinf( a ); // row major mat4 m; m[0] = u.x * u.x + (1 - u.x * u.x) * c, m[1] = u.x * u.y * l_c + u.z * s, m[2] = u.x * u.z * l_c - u.y * s, m[3] = 0; m[4] = u.x * u.y * l_c - u.z * s, m[5] = u.y * u.y + (1 - u.y * u.y) * c, m[6] = u.y * u.z * l_c + u.x * s, m[7] = 0; m[8] = u.x * u.z * l_c + u.y * s, m[9] = u.y * u.z * l_c - u.x * s, m[10] = u.z * u.z + (1 - u.z * u.z) * c, m[11] = 0; m[12] = m[13] = m[14] = 0, m[15] = 1; return m; } static mat4 LookAt( const float3 P, const float3 T ) { const float3 z = normalize( T - P ); const float3 x = normalize( cross( z, float3( 0, 1, 0 ) ) ); const float3 y = cross( x, z ); mat4 M = Translate( P ); M[0] = x.x, M[4] = x.y, M[8] = x.z; M[1] = y.x, M[5] = y.y, M[9] = y.z; M[2] = z.x, M[6] = z.y, M[10] = z.z; return M; } static mat4 Translate( const float x, const float y, const float z ) { mat4 r = mat4::Identity(); r.cell[3] = x; r.cell[7] = y; r.cell[11] = z; return r; }; static mat4 Translate( const float3 P ) { mat4 r = mat4::Identity(); r.cell[3] = P.x; r.cell[7] = P.y; r.cell[11] = P.z; return r; }; void Invert() { // from MESA, via http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix const float inv[16] = { cell[5] * cell[10] * cell[15] - cell[5] * cell[11] * cell[14] - cell[9] * cell[6] * cell[15] + cell[9] * cell[7] * cell[14] + cell[13] * cell[6] * cell[11] - cell[13] * cell[7] * cell[10], -cell[1] * cell[10] * cell[15] + cell[1] * cell[11] * cell[14] + cell[9] * cell[2] * cell[15] - cell[9] * cell[3] * cell[14] - cell[13] * cell[2] * cell[11] + cell[13] * cell[3] * cell[10], cell[1] * cell[6] * cell[15] - cell[1] * cell[7] * cell[14] - cell[5] * cell[2] * cell[15] + cell[5] * cell[3] * cell[14] + cell[13] * cell[2] * cell[7] - cell[13] * cell[3] * cell[6], -cell[1] * cell[6] * cell[11] + cell[1] * cell[7] * cell[10] + cell[5] * cell[2] * cell[11] - cell[5] * cell[3] * cell[10] - cell[9] * cell[2] * cell[7] + cell[9] * cell[3] * cell[6], -cell[4] * cell[10] * cell[15] + cell[4] * cell[11] * cell[14] + cell[8] * cell[6] * cell[15] - cell[8] * cell[7] * cell[14] - cell[12] * cell[6] * cell[11] + cell[12] * cell[7] * cell[10], cell[0] * cell[10] * cell[15] - cell[0] * cell[11] * cell[14] - cell[8] * cell[2] * cell[15] + cell[8] * cell[3] * cell[14] + cell[12] * cell[2] * cell[11] - cell[12] * cell[3] * cell[10], -cell[0] * cell[6] * cell[15] + cell[0] * cell[7] * cell[14] + cell[4] * cell[2] * cell[15] - cell[4] * cell[3] * cell[14] - cell[12] * cell[2] * cell[7] + cell[12] * cell[3] * cell[6], cell[0] * cell[6] * cell[11] - cell[0] * cell[7] * cell[10] - cell[4] * cell[2] * cell[11] + cell[4] * cell[3] * cell[10] + cell[8] * cell[2] * cell[7] - cell[8] * cell[3] * cell[6], cell[4] * cell[9] * cell[15] - cell[4] * cell[11] * cell[13] - cell[8] * cell[5] * cell[15] + cell[8] * cell[7] * cell[13] + cell[12] * cell[5] * cell[11] - cell[12] * cell[7] * cell[9], -cell[0] * cell[9] * cell[15] + cell[0] * cell[11] * cell[13] + cell[8] * cell[1] * cell[15] - cell[8] * cell[3] * cell[13] - cell[12] * cell[1] * cell[11] + cell[12] * cell[3] * cell[9], cell[0] * cell[5] * cell[15] - cell[0] * cell[7] * cell[13] - cell[4] * cell[1] * cell[15] + cell[4] * cell[3] * cell[13] + cell[12] * cell[1] * cell[7] - cell[12] * cell[3] * cell[5], -cell[0] * cell[5] * cell[11] + cell[0] * cell[7] * cell[9] + cell[4] * cell[1] * cell[11] - cell[4] * cell[3] * cell[9] - cell[8] * cell[1] * cell[7] + cell[8] * cell[3] * cell[5], -cell[4] * cell[9] * cell[14] + cell[4] * cell[10] * cell[13] + cell[8] * cell[5] * cell[14] - cell[8] * cell[6] * cell[13] - cell[12] * cell[5] * cell[10] + cell[12] * cell[6] * cell[9], cell[0] * cell[9] * cell[14] - cell[0] * cell[10] * cell[13] - cell[8] * cell[1] * cell[14] + cell[8] * cell[2] * cell[13] + cell[12] * cell[1] * cell[10] - cell[12] * cell[2] * cell[9], -cell[0] * cell[5] * cell[14] + cell[0] * cell[6] * cell[13] + cell[4] * cell[1] * cell[14] - cell[4] * cell[2] * cell[13] - cell[12] * cell[1] * cell[6] + cell[12] * cell[2] * cell[5], cell[0] * cell[5] * cell[10] - cell[0] * cell[6] * cell[9] - cell[4] * cell[1] * cell[10] + cell[4] * cell[2] * cell[9] + cell[8] * cell[1] * cell[6] - cell[8] * cell[2] * cell[5] }; const float det = cell[0] * inv[0] + cell[1] * inv[4] + cell[2] * inv[8] + cell[3] * inv[12]; if (det != 0) { const float invdet = 1.0f / det; for (int i = 0; i < 16; i++) cell[i] = inv[i] * invdet; } } }; mat4 operator * ( const mat4& a, const mat4& b ); bool operator == ( const mat4& a, const mat4& b ); bool operator != ( const mat4& a, const mat4& b ); float4 operator * ( const mat4& a, const float4& b ); float4 operator * ( const float4& a, const mat4& b ); #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) void FatalError( const char* file, int line, const char* message ); void FatalError( const char* file, int line, const char* message, const char* context ); int GetScreenWidth(); int GetScreenHeight(); bool AppHasFocus(); class Thread { public: Thread() { thread = 0; } void start(); virtual void run() {}; unsigned long* thread; }; extern "C" { unsigned int sthread_proc( void* param ); } // framework includes #include "gltools.h" #include "cudatools.h" #include "shader.h" #include "gltexture.h" #include "hostapp.h" namespace cudalab { #include "shared.h" }; // library namespace using namespace cudalab; // global helper functions float GetTime(); void StartTimer(); float GetDuration(); bool FileIsNewer( const char* file1, const char* file2 ); bool FileExists( const char* f ); // random numbers inline float Rand( float range ) { return ((float)rand() / RAND_MAX) * range; } inline int IRand( int range ) { return rand() % range; } // generic swap template void Swap( T& x, T& y ) { T t; t = x; x = y; y = t; } // timer struct Timer { typedef long long value_type; static double inv_freq; value_type start; Timer() : start( get() ) { init(); } float elapsed() const { return (float)((get() - start) * inv_freq); } static value_type get() { LARGE_INTEGER c; QueryPerformanceCounter( &c ); return c.QuadPart; } static double to_time( const value_type vt ) { return double( vt ) * inv_freq; } void reset() { start = get(); } static void init() { LARGE_INTEGER f; QueryPerformanceFrequency( &f ); inv_freq = 1000. / double( f.QuadPart ); } }; namespace cudalab { class Bitmap { public: Bitmap( uint w, uint h ) : pixels( new uint[w * h] ), width( w ), height( h ) {} void Clear() { memset( pixels, 0, width * height * 4 ); } uint* pixels, width, height; }; class DebugPanel { public: DebugPanel( float _x1, float _y1, float _x2, float y2 ); void Clear(); void Print( char* t, int x, int y, uint c ); void DrawBar( uint x1, uint y1, uint x2, uint y2, uint c ); void Present(); void Plot( int x, int y, uint c ); Bitmap* GetBitmap() { return debugBitmap; } private: float x1, y1, x2, y2; GLTexture* debugTexture; Bitmap* debugBitmap; }; } // namespace cudalab // EOF