#include "system.h" #pragma comment( linker, "/subsystem:windows /ENTRY:mainCRTStartup" ) static bool running = true; static HostApp* hostApp = 0; GLFWwindow* window = 0; double Timer::inv_freq = 1; // Math Stuff // ---------------------------------------------------------------------------- float3 normalize( const float3& v ) { return v.normalized(); } float length( const float4& v ) { return sqrtf( v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w ); } float length( const float3& v ) { return sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); } float length( const float2& v ) { return sqrtf( v.x * v.x + v.y * v.y ); } float3 cross( const float3& a, const float3& b ) { return a.cross( b ); } float dot( const float3& a, const float3& b ) { return a.dot( b ); } float dot( const float2& a, const float2& b ) { return a.dot( b ); } float3 lerp( const float3& a, const float3& b, const float t ) { return (a + t * (b - a)); } float3 operator * ( const float& s, const float3& v ) { return float3( v.x * s, v.y * s, v.z * s ); } float3 operator * ( const float3& v, const float& s ) { return float3( v.x * s, v.y * s, v.z * s ); } mat4 operator * ( const mat4& a, const mat4& b ) { mat4 r; for (unsigned int i = 0; i < 16; i += 4) for (unsigned int j = 0; j < 4; ++j) r.cell[i + j] = (b.cell[i + 0] * a.cell[j + 0]) + (b.cell[i + 1] * a.cell[j + 4]) + (b.cell[i + 2] * a.cell[j + 8]) + (b.cell[i + 3] * a.cell[j + 12]); return r; } bool operator == ( const mat4& a, const mat4& b ) { for (unsigned int i = 0; i < 16; i++) if (a.cell[i] != b.cell[i]) return false; return true; } bool operator != ( const mat4& a, const mat4& b ) { return !(a == b); } float4 operator * ( const mat4& a, const float4& b ) { return float4( a.cell[0] * b.x + a.cell[1] * b.y + a.cell[2] * b.z + a.cell[3] * b.w, a.cell[4] * b.x + a.cell[5] * b.y + a.cell[6] * b.z + a.cell[7] * b.w, a.cell[8] * b.x + a.cell[9] * b.y + a.cell[10] * b.z + a.cell[11] * b.w, a.cell[12] * b.x + a.cell[13] * b.y + a.cell[14] * b.z + a.cell[15] * b.w ); } float4 operator * ( const float4& b, const mat4& a ) { return float4( a.cell[0] * b.x + a.cell[1] * b.y + a.cell[2] * b.z + a.cell[3] * b.w, a.cell[4] * b.x + a.cell[5] * b.y + a.cell[6] * b.z + a.cell[7] * b.w, a.cell[8] * b.x + a.cell[9] * b.y + a.cell[10] * b.z + a.cell[11] * b.w, a.cell[12] * b.x + a.cell[13] * b.y + a.cell[14] * b.z + a.cell[15] * b.w ); } // FatalError // Generic error handling; called by FATALERROR macro. // ---------------------------------------------------------------------------- void FatalError( const char* file, int line, const char* message ) { char t[8192]; sprintf( t, "%s, line %i:\n%s", file, line, message ); MessageBox( NULL, t, "Error", MB_OK | MB_ICONEXCLAMATION ); exit( 0 ); } void FatalError( const char* file, int line, const char* message, const char* context ) { char t[3000]; sprintf( t, "%s, line %i:\n%s", file, line, message ); MessageBox( NULL, t, context, MB_OK | MB_ICONEXCLAMATION ); exit( 0 ); } // AppHasFocus // Returns true if this app is currently in focus // ---------------------------------------------------------------------------- bool AppHasFocus() { bool hasFocus = false; HWND activeWindow = GetForegroundWindow(); if (activeWindow) { DWORD activeProcess = 0; GetWindowThreadProcessId( activeWindow, &activeProcess ); DWORD thisProcess = GetCurrentProcessId(); if (thisProcess == activeProcess) hasFocus = true; } return hasFocus; } // FileIsNewer // returns true if second file doesn't exist or first file is newer // ---------------------------------------------------------------------------- bool FileIsNewer( const char* file1, const char* file2 ) { HANDLE fh1 = CreateFile( file1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); HANDLE fh2 = CreateFile( file2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (fh1 == INVALID_HANDLE_VALUE) FatalError( __FILE__, __LINE__, file1, "file not found" ); if (fh2 == INVALID_HANDLE_VALUE) { CloseHandle( fh1 ); return true; // second file does not exist } FILETIME ft1, ft2; GetFileTime( fh1, NULL, NULL, &ft1 ); GetFileTime( fh2, NULL, NULL, &ft2 ); int result = CompareFileTime( &ft1, &ft2 ); CloseHandle( fh1 ); CloseHandle( fh2 ); return (result != -1); } // FileExists // returns true if the file exists // ---------------------------------------------------------------------------- bool FileExists( const char* f ) { HANDLE fh = CreateFile( f, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (fh == INVALID_HANDLE_VALUE) return false; CloseHandle( fh ); return true; } // GetTime // Reasonably accurate time in a float // ---------------------------------------------------------------------------- float GetTime() { LARGE_INTEGER freq, value; QueryPerformanceCounter( &value ); QueryPerformanceFrequency( &freq ); return (float)((double)value.QuadPart / (double)freq.QuadPart); } // StartTimer // Mark the start of a time period to measure // ---------------------------------------------------------------------------- static LONGLONG startTime = 0; void StartTimer() { LARGE_INTEGER value; QueryPerformanceCounter( &value ); startTime = value.QuadPart; } // GetDuration // Get the duration since calling StartTimer // ---------------------------------------------------------------------------- float GetDuration() { LARGE_INTEGER freq, value; LONGLONG elapsed; QueryPerformanceCounter( &value ); QueryPerformanceFrequency( &freq ); elapsed = value.QuadPart - startTime; return (float)((double)elapsed / (double)freq.QuadPart); } // ReshapeWindow // Any operations required after a window resize go here. // ---------------------------------------------------------------------------- void ReshapeWindowCallback( GLFWwindow* window, int width, int height ) { // TODO; received resize event from glfw int w = 0; } // ReshapeWindow // Any operations required after a window resize go here. // ---------------------------------------------------------------------------- void KeyEventCallback( GLFWwindow* window, int key, int scancode, int action, int mods ) { // TODO; received resize event from glfw int w = 0; } // WinMain // Application entry point and message pump. // ---------------------------------------------------------------------------- int main() { // setup glfw if (!glfwInit()) exit( EXIT_FAILURE ); glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 ); glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); glfwWindowHint( GLFW_RESIZABLE, GL_FALSE ); window = glfwCreateWindow( WINDOWWIDTH, WINDOWHEIGHT, "CUDA Template", nullptr, nullptr ); if (!window) exit( EXIT_FAILURE ); glfwMakeContextCurrent( window ); glfwSetFramebufferSizeCallback( window, ReshapeWindowCallback ); glfwSetKeyCallback( window, KeyEventCallback ); if (!gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress )) exit( EXIT_FAILURE ); // prepare OpenGL state glViewport( 0, 0, WINDOWWIDTH, WINDOWHEIGHT ); glDisable( GL_BLEND ); glDisable( GL_DEPTH_TEST ); glDisable( GL_CULL_FACE ); // glfw main loop hostApp = new HostApp(); hostApp->Init(); while (!glfwWindowShouldClose( window )) { glfwPollEvents(); hostApp->Tick(); glfwSwapBuffers( window ); } // clean up hostApp->Shutdown(); glfwDestroyWindow( window ); glfwTerminate(); return 0; } // Thread::start // Start a thread. // ---------------------------------------------------------------------------- unsigned int sthread_proc( void* param ) { Thread* tp = (Thread*)param; tp->run(); return 0; } void Thread::start() { DWORD tid = 0; thread = (unsigned long*)CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)sthread_proc, (Thread*)this, 0, &tid ); SetThreadPriority( thread, THREAD_PRIORITY_NORMAL ); } // DebugPanel // Simple debug thingy // ---------------------------------------------------------------------------- DebugPanel::DebugPanel( float _x1, float _y1, float _x2, float _y2 ) : x1( _x1 ), y1( _y1 ), x2( _x2 ), y2( _y2 ) { float sx1 = (_x1 + 1) * 0.5f * WINDOWWIDTH; float sy2 = (_y1 + 1) * 0.5f * WINDOWHEIGHT; float sx2 = (_x2 + 1) * 0.5f * WINDOWWIDTH; float sy1 = (_y2 + 1) * 0.5f * WINDOWHEIGHT; debugBitmap = new Bitmap( (int)(sx2 - sx1 + 0.5f), (int)(sy2 - sy1 + 0.5f) ); debugTexture = new GLTexture( (int)(sx2 - sx1 + 0.5f), (int)(sy2 - sy1 + 0.5f) ); Clear(); debugTexture->CopyFrom( debugBitmap ); } void DebugPanel::Print( char* t, int x, int y, uint c ) { static uint f[] = { /* font obtained from sharefonts.net */ 18859582, 33078847, 32539710, 16303663, 32554047, 1096767, 33088574, 18415153, 32641183, 16302616, 18128177, 32539681, 18405233, 18667121, 15255086, 1097263, 5228094, 18398767, 33061950, 4329631, 15255089, 4532785, 11195953, 18157905, 4336177, 32575775, 33150782, 14815428, 32553487, 16267807, 5215265, 16268351, 33094718, 4334111, 33095230, 16285230, 31744, 4357252, 4198694, 4194304, 4456448, 8654914, 2167048, 4198532, 11512810, 17895697, 23386150, 4261956, 2232450, 32505856, 1016800, 12718220, 12853516, 4194308, 4194308, 10, 8521864, 4473092, 0 }, l[256] = { 999 }; if (l[0] == 999) { char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+?,.\\/!#~&()_=[]:;\"<> "; for (int i = 0; i < strlen( s ); i++) l[s[i]] = i; l[0] = 0; } for (int i = 0; i < strlen( t ); i++) { uint c = f[l[toupper( t[i] )]], *a = debugBitmap->pixels + x + i * 6 + y * debugBitmap->width, j = 0; for (int v = 0; v < 5; v++, a += debugBitmap->width) for (int h = 0; h < 5; h++, j++) if (c & (1 << j)) a[h] = c; } } void DebugPanel::Clear() { int pixels = debugBitmap->width * debugBitmap->height; for (int i = 0; i < pixels; i++) debugBitmap->pixels[i] = 0x77000000; } void DebugPanel::DrawBar( uint x1, uint y1, uint x2, uint y2, uint c ) { uint* a = debugBitmap->pixels + y1 * debugBitmap->width; const uint h = y2 - y1; for (uint y = 0; y < h; y++, a += debugBitmap->width) for (uint x = x1; x < x2; x++) a[x] = c; } void DebugPanel::Present() { debugTexture->CopyFrom( debugBitmap ); glColor3f( 1, 1, 1 ); glDisable( GL_DEPTH_TEST ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glUseProgram( 0 ); glBegin( GL_QUADS ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( x1, y2, 0.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( x2, y2, 0.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( x2, y1, 0.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( x1, y1, 0.0f ); glEnd(); glDisable( GL_BLEND ); } void DebugPanel::Plot( int x, int y, uint c ) { debugBitmap->pixels[x + y * debugBitmap->width] = c; } // EOF