//#define NOMUSICTIMING #define MULTISHADER #define LOCALMUSIC #ifdef _DEBUG #include #include #include #include #include "Shaders.h" #include "small.h" #include "synth.h" #else #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include #include #include #include #include "glext.h" #include "small.h" #ifdef LOCALMUSIC #include "mmsystem.h" #include "mmreg.h" #include "4klang.h" #define USE_SOUND_THREAD //////////////////////////////////////////////// // sound //////////////////////////////////////////////// #define SAMPLE_RATE 44100 #define MAX_SAMPLES SAMPLE_RATE*2*60*4 #pragma bss_seg(".synthnothing") static float lpSoundBuffer[MAX_SAMPLES]; static HWAVEOUT hWaveOut; ///////////////////////////////////////////////////////////////////////////////// // initialized data ///////////////////////////////////////////////////////////////////////////////// #pragma data_seg(".wavefmt") WAVEFORMATEX WaveFMT = { WAVE_FORMAT_IEEE_FLOAT, 2, // channels SAMPLE_RATE, // samples per sec SAMPLE_RATE*4*2, // bytes per sec 8, // block alignment; 32, // bits per sample 0 // extension not needed }; #pragma data_seg(".wavehdr") WAVEHDR WaveHDR = { (LPSTR)lpSoundBuffer, MAX_SAMPLES*4, 0, 0, 0, 0, 0, 0 }; #pragma data_seg(".mmtime") MMTIME MMTime = { TIME_SAMPLES, 0 }; #ifdef USE_SOUND_THREAD #pragma code_seg(".sndthrd") DWORD WINAPI SoundThread( LPVOID lpParam ) { _4klang_render(lpSoundBuffer); return 0; } #endif #else #include "synth.h" #endif #ifdef NOMUSICTIMING #include "Mmsystem.h" #endif #define V_Y "Y" #define V_Z "Z" #ifndef ASPECT #define ASPECT 1.78 #endif #ifndef SCREENWIDTH #define SCREENWIDTH 800 #endif #ifndef SCREENHEIGHT #define SCREENHEIGHT 600 #endif //#define WINDOWED #pragma data_seg(".Shader0") #include "mark_small.h" #define STR2(x) #x #define STR(x) STR2(x) #pragma data_seg(".vertexshader") //static char* vsh = "out vec4 Y;out vec2 Z;void main(){Y=gl_Color;Z=(gl_Vertex.xy*vec2(Y.w,1))*.5+.5;gl_Position=gl_Vertex;}"; static char* vsh = "varying vec2 "I_Y","I_Z";void main(){"I_Y"=gl_Color.xy;"I_Z"=(gl_Vertex.xy*vec2("STR( ASPECT )",1))*.5+.5;gl_Position=gl_Vertex;}"; #endif #ifdef _DEBUG #define HALF_FAC 2 #pragma data_seg(".resolutionX") static const int gi_ScreenWidth = 1280/HALF_FAC; #pragma data_seg(".resolutionY") static const int gi_ScreenHeight = 720/HALF_FAC; #else #pragma data_seg(".resolutionX") static const int gi_ScreenWidth = SCREENWIDTH; #pragma data_seg(".resolutionY") static const int gi_ScreenHeight = SCREENHEIGHT ; #endif #ifdef _DEBUG #pragma bss_seg(".debugnothing") HANDLE gh_ShaderCompileEvent; static char** gs_LastShader_; static __time64_t gi_ShaderChangedDate; static unsigned int gi_ShaderProgram; static unsigned int gi_LastShaderProgram; #pragma data_seg(".debuginfo") static const char* gs_VertexShader = "generic.vs"; static const char* gs_ShaderFile = "mark.fs"; #endif #pragma data_seg(".pfd") static const PIXELFORMATDESCRIPTOR pfd={ 0, 1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; #pragma data_seg(".dms") static DEVMODE dmScreenSettings={ "",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT, 0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,gi_ScreenWidth,gi_ScreenHeight }; #pragma code_seg(".compile") __forceinline unsigned int compileShader(const char* vsh, const char* fsh) { GLuint s,p; p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))(); s = ((PFNGLCREATESHADERPROC)(wglGetProcAddress("glCreateShader")))(GL_VERTEX_SHADER); ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &vsh, NULL); ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s); ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s); s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &fsh, NULL); ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s); ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s); ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p); #ifndef MULTISHADER ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(p); #endif return p; } __forceinline unsigned int compileShaderMultiple(const char* vsh, const char** fsh) { GLuint s,p; p = ((PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"))(); s = ((PFNGLCREATESHADERPROC)(wglGetProcAddress("glCreateShader")))(GL_VERTEX_SHADER); ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 1, &vsh, NULL); ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s); ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s); s = ((PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"))(GL_FRAGMENT_SHADER); ((PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource")) (s, 7, fsh, NULL); ((PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"))(s); ((PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader")) (p,s); ((PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"))(p); #ifndef MULTISHADER ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(p); #endif return p; } #ifdef _DEBUG #define CHECK_DEBUG_OUTPUT(shader) \ {\ GLint success = 0;\ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);\ if (!success)\ {\ GLchar infoLog[16384];\ glGetShaderInfoLog(shader, 16384, NULL, infoLog);\ OutputDebugString(infoLog);\ }\ } #else #define CHECK_DEBUG_OUTPUT(shader) #endif #pragma code_seg(".main") #ifdef _DEBUG DWORD WINAPI filemon(void* args) { while (true) { _finddata_t fdata; long hfile = _findfirst(gs_ShaderFile, &fdata); if (hfile != -1) { if (fdata.time_write != gi_ShaderChangedDate) { gi_ShaderChangedDate = fdata.time_write; ::SetEvent(gh_ShaderCompileEvent); OutputDebugString("Shader loaded.\n"); } _findclose(hfile); } ::Sleep(100); } return 0; } #endif #ifdef _DEBUG #include float g_DebugCamPos[ 3 ]= {0,2.0f,-48.0f}; float g_DebugCamRot[ 2 ]= {0,0}; bool g_ShaderDebug= true; int g_ShaderID= 0; int g_SceneID= 0; int g_MaxSceneID= 16; float g_fSqrAnimFac= 0.0f; float g_fSpeedFac= 12.0f; bool g_bForceCompile= true; void MoveCam( float& fCurTime ) { float fSpeed= 0.125f*3.0f; bool bShift= GetAsyncKeyState( VK_SHIFT ) || GetAsyncKeyState( VK_MBUTTON ) || GetAsyncKeyState( VK_RBUTTON ); bool bStrg= GetAsyncKeyState( VK_CONTROL ) != 0; float a= g_DebugCamRot[ 0 ]; float b= g_DebugCamRot[ 1 ]; float g_Forward[ 3 ]= {sinf( a )*cosf(b),-sinf(b), cosf( a )*cosf(b)}; float g_Right[ 3 ]= {cosf( a ),0, -sinf( a )}; if( bShift ) { if( GetAsyncKeyState( VK_HOME ) ) { g_DebugCamPos[ 0 ]= 0.0f; g_DebugCamPos[ 1 ]= 2.0f; g_DebugCamPos[ 2 ]= -48.0f; g_DebugCamRot[ 0 ]= 0.0f; g_DebugCamRot[ 1 ]= 0.0f; } if( GetAsyncKeyState( 'W' ) ) { g_DebugCamPos[ 0 ]+= fSpeed * g_Forward[ 0 ]; g_DebugCamPos[ 1 ]+= fSpeed * g_Forward[ 1 ]; g_DebugCamPos[ 2 ]+= fSpeed * g_Forward[ 2 ]; } if( GetAsyncKeyState( 'S' ) ) { g_DebugCamPos[ 0 ]-= fSpeed * g_Forward[ 0 ]; g_DebugCamPos[ 1 ]-= fSpeed * g_Forward[ 1 ]; g_DebugCamPos[ 2 ]-= fSpeed * g_Forward[ 2 ]; } if( GetAsyncKeyState( 'A' ) ) { g_DebugCamPos[ 0 ]-= fSpeed * g_Right[ 0 ]; g_DebugCamPos[ 1 ]-= fSpeed * g_Right[ 1 ]; g_DebugCamPos[ 2 ]-= fSpeed * g_Right[ 2 ]; } if( GetAsyncKeyState( 'D' ) ) { g_DebugCamPos[ 0 ]+= fSpeed * g_Right[ 0 ]; g_DebugCamPos[ 1 ]+= fSpeed * g_Right[ 1 ]; g_DebugCamPos[ 2 ]+= fSpeed * g_Right[ 2 ]; } if( GetAsyncKeyState( 'F' ) ) { g_DebugCamPos[ 1 ]+= fSpeed; } if( GetAsyncKeyState( 'V' ) ) { g_DebugCamPos[ 1 ]-= fSpeed; } if( bStrg ) { if( ( GetAsyncKeyState( VK_F2 ) & 1 ) != 0) { g_ShaderDebug= !g_ShaderDebug; g_bForceCompile= true; } if( ( GetAsyncKeyState( VK_F3 ) & 1 ) != 0) { g_ShaderID= (g_ShaderID + MAX_SHADER_ID - 1 ) % MAX_SHADER_ID; g_bForceCompile= true; } if( ( GetAsyncKeyState( VK_F4 ) & 1 )!= 0) { g_ShaderID= (g_ShaderID + MAX_SHADER_ID + 1 ) % MAX_SHADER_ID; g_bForceCompile= true; } if( ( GetAsyncKeyState( VK_F7 ) & 1 ) != 0) { g_SceneID= (g_SceneID + g_MaxSceneID - 1 ) % g_MaxSceneID; } if( ( GetAsyncKeyState( VK_F8 ) & 1 )!= 0) { g_SceneID= (g_SceneID + g_MaxSceneID + 1 ) % g_MaxSceneID; } if( ( GetAsyncKeyState( VK_F9 ) & 1 ) != 0) { g_fSqrAnimFac-= 1.0f; } if( ( GetAsyncKeyState( VK_F10 ) & 1 )!= 0) { g_fSqrAnimFac+= 1.0f; } } else { if( ( GetAsyncKeyState( VK_F6 ) & 1 )!= 0) { fCurTime= 0.0f; } if( ( GetAsyncKeyState( VK_F7 ) & 1 )!= 0) { g_fSpeedFac*= 2.0f; if( g_fSpeedFac > 32.0f ) { g_fSpeedFac= 32.0f; } } if( ( GetAsyncKeyState( VK_F8 ) & 1 ) != 0) { g_fSpeedFac/= 2.0f; if( g_fSpeedFac < 2.0f ) { g_fSpeedFac= 2.0f; } } } } static POINT OldCurPos; POINT CurPos; GetCursorPos( &CurPos ); if( bShift ) { g_DebugCamRot[ 0 ]-= 0.003f * ( OldCurPos.x - CurPos.x ); g_DebugCamRot[ 1 ]-= 0.003f * ( OldCurPos.y - CurPos.y ); g_DebugCamRot[ 1 ]= max( g_DebugCamRot[ 1 ], -1.56f ); g_DebugCamRot[ 1 ]= min( g_DebugCamRot[ 1 ], 1.56f ); } OldCurPos= CurPos; } #endif #ifdef _DEBUG LRESULT MessageCallback(HWND ar_Handle, UINT aw_Message, WPARAM aw_Param, LPARAM al_Param) { return DefWindowProc(ar_Handle, aw_Message, aw_Param, al_Param); } #endif #pragma data_seg(".main_glob") //int gCurScene= 0; const int g_SceneLength= 16; void _cdecl main() { #ifdef _DEBUG //ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN); //HDC hDC = GetDC(CreateWindow("edit", 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0)); //HWND hWnd = CreateWindow("MDICLIENT", "Test", WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU, 0, 0, gi_ScreenWidth, gi_ScreenHeight, 0, 0, 0, 0); WNDCLASSEX wndclass; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndclass.lpfnWndProc = (WNDPROC)MessageCallback ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = NULL ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (DKGRAY_BRUSH) ; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "Window" ; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx(&wndclass); HWND hWnd = CreateWindow( "Window", /* Classname */ "Title", /* Title Text */ WS_EX_APPWINDOW, /* default window */ 10, /* Windows decides the position */ 30, /* where the window ends up on the screen */ gi_ScreenWidth, /* The programs width */ gi_ScreenHeight, /* and height in pixels */ NULL, /* The window is a child-window to desktop */ NULL, /* No menu */ GetModuleHandle(NULL), //GetModuleHandle(NULL), /* Program Instance handler */ NULL /* No Window Creation data */ ); HDC hDC = GetDC(hWnd); SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd); wglMakeCurrent(hDC, wglCreateContext(hDC)); initShaders(); gh_ShaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, 0, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); ShowWindow (hWnd , SW_NORMAL ); ::Sleep(100); #else #ifndef WINDOWED ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN); HDC hDC = GetDC(CreateWindow("edit", 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0)); #else HDC hDC = GetDC(CreateWindow("static", "RED", WS_EX_APPWINDOW | WS_VISIBLE | WS_SYSMENU, 0, 0, gi_ScreenWidth, gi_ScreenHeight, 0, 0, 0, 0)); #endif SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd); wglMakeCurrent(hDC, wglCreateContext(hDC)); #ifdef LOCALMUSIC #ifdef USE_SOUND_THREAD CreateThread(0, 0, SoundThread, 0, 0, 0); #else _4klang_render(lpSoundBuffer); #endif #endif #ifdef MULTISHADER unsigned int shaders[4]; /*shaders[0]=compileShader(vsh, mark_fs_0 ); mark_fs_0[6]++; shaders[1]=compileShader(vsh, mark_fs_0 ); mark_fs_0[6]++; shaders[2]=compileShader(vsh, mark_fs_0 ); mark_fs_0[6]++; shaders[3]=compileShader(vsh, mark_fs_0 );*/ shaders[0]=compileShaderMultiple(vsh, ShaderSource1 ); shaders[1]=compileShaderMultiple(vsh, ShaderSource2 ); shaders[2]=compileShaderMultiple(vsh, ShaderSource3 ); shaders[3]=compileShaderMultiple(vsh, ShaderSource4 ); #else compileShader(vsh, mark_fs_0 ); #endif ShowCursor(FALSE); #endif #ifdef _DEBUG if (::WaitForSingleObject(gh_ShaderCompileEvent, 0) == WAIT_OBJECT_0) { ::Sleep(250); gi_ShaderProgram = createProgram( createVertexShader(gs_VertexShader), createFragmentShader(gs_ShaderFile, g_ShaderID, g_ShaderDebug )); ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(gi_ShaderProgram); PrintErrors(); } glColor4f(0,0,0, float(gi_ScreenWidth)/gi_ScreenHeight); glRectf(-1, -1, 1, 1); SwapBuffers(hDC); #endif SwapBuffers(hDC); Sleep(13000); #ifndef _DEBUG #ifdef LOCALMUSIC waveOutOpen ( &hWaveOut, WAVE_MAPPER, &WaveFMT, NULL, 0, CALLBACK_NULL ); waveOutPrepareHeader( hWaveOut, &WaveHDR, sizeof(WaveHDR) ); waveOutWrite ( hWaveOut, &WaveHDR, sizeof(WaveHDR) ); #else InitSound(); #endif #else LARGE_INTEGER li_OldTime = { 0 }; #endif #ifdef NOMUSICTIMING int iStartTick= timeGetTime(); #endif int Sample; #ifdef _DEBUG float lf_Time= 0.0f; #endif do { SwapBuffers(hDC); #ifdef _DEBUG MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return; else { TranslateMessage(&msg); DispatchMessage(&msg); } } if (::WaitForSingleObject(gh_ShaderCompileEvent, 0) == WAIT_OBJECT_0 || g_bForceCompile) { ::Sleep(50); gi_ShaderProgram = createProgram( createVertexShader(gs_VertexShader), createFragmentShader(gs_ShaderFile, g_ShaderID, g_ShaderDebug)); ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(gi_ShaderProgram); PrintErrors(); g_bForceCompile= false; } #endif #ifndef LOCALMUSIC int Sample= get_Sample() - gCurSceneStart; const int SceneEnd= g_SceneLength * (44100 * 60 / float(BPM));//samples per tick #endif //lf_Time = get_Time() * 71.0f / 240.0f; #ifdef NOMUSICTIMING lf_Time = ( timeGetTime() - iStartTick ) * 0.001f / 16.0f; #endif glLoadIdentity(); #ifdef _DEBUG LARGE_INTEGER li_CurrentTime, li_CurrentFrequency; QueryPerformanceCounter(&li_CurrentTime); QueryPerformanceFrequency(&li_CurrentFrequency); //lf_Time = (float)li_CurrentTime.QuadPart / (float)li_CurrentFrequency.QuadPart; float lf_DiffTime = (float)(li_CurrentTime.QuadPart - li_OldTime.QuadPart) / (float)li_CurrentFrequency.QuadPart; char windowText[255]; sprintf_s( windowText, "Shader: %d Scene: %d AnimFac: %2.2f FPS: %.2f, Render time: %.4fms", g_ShaderID, g_SceneID, g_fSqrAnimFac, 1.0f / lf_DiffTime, lf_DiffTime ); ::SetWindowTextA(hWnd, windowText); li_OldTime = li_CurrentTime; lf_Time+= lf_DiffTime * 135.0f / 60.0f / g_fSpeedFac; if( lf_Time > 1.0f ) { lf_Time= 0.0f; if( g_ShaderID == 1 ) { g_SceneID= (g_SceneID+1)%16; } } float fValue= g_SceneID + lf_Time; glColor3f(fValue, fValue, fValue); #else #ifdef LOCALMUSIC waveOutGetPosition(hWaveOut, &MMTime, sizeof(MMTIME)); Sample= MMTime.u.sample; float lf_Time= (float)(Sample)/(float)313600; #else lf_Time= (float)Sample / (float)SceneEnd; #endif #ifdef MULTISHADER ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(shaders[ Sample/(4*313600) ]); #endif glColor3f(lf_Time, lf_Time, lf_Time); #endif #ifdef _DEBUG MoveCam( lf_Time ); float fDebugData[ 16 ]; fDebugData[ 0 ]= g_DebugCamPos[ 0 ]; fDebugData[ 1 ]= g_DebugCamPos[ 1 ]; fDebugData[ 2 ]= g_DebugCamPos[ 2 ]; fDebugData[ 4 ]= g_DebugCamRot[ 0 ]; fDebugData[ 5 ]= g_DebugCamRot[ 1 ]; glMatrixMode(GL_MODELVIEW); glLoadMatrixf((GLfloat*)&fDebugData); #endif glRects(-1, -1, 1, 1); #ifndef _DEBUG #ifdef LOCALMUSIC #else if( Sample > SceneEnd ) { gCurSceneStart+= SceneEnd; gCurScene++; } #endif #endif } #ifdef _DEBUG while ( !GetAsyncKeyState(VK_ESCAPE) ); #else while ( Sample < (313600*16) && !GetAsyncKeyState(VK_ESCAPE) ); #endif ExitProcess(0); }