#include #include #include #include "Shaders.h" HWND hWnd; static const int gi_ScreenWidth = 1280; static const int gi_ScreenHeight = 720; static const int textureSize = 2048; static const char* gs_VertexShader = "vertex.glsl"; static const char* gs_ShaderFile = "fragment.glsl"; 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 }; 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 }; #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);\ }\ } struct filemon_struct { unsigned int shaderProgram; char* shaderFile; HANDLE shaderCompileEvent; __time64_t shaderChangedDate; }; DWORD WINAPI filemon(void* args) { filemon_struct* data = (filemon_struct*)args; while (true) { _finddata_t fdata; long hfile = _findfirst(data->shaderFile, &fdata); if (hfile != -1) { if (fdata.time_write != data->shaderChangedDate) { data->shaderChangedDate = fdata.time_write; ::SetEvent(data->shaderCompileEvent); std::cout << "Shader loaded." << std::endl; } _findclose(hfile); } ::Sleep(100); } return 0; } #include float g_DebugCamPos[ 3 ]= {0,0.0f,0.0f}; float g_DebugCamRot[ 2 ]= {0,0}; bool g_ShaderDebug= true; int g_ShaderID= 0; int g_SceneID= 0; int g_MaxSceneID= 17; float g_fSpeedFac= 1.0f; bool g_bForceCompile= true; void MoveCam( float& fCurTime, float& fDeltaTime ) { if (GetActiveWindow() != hWnd) return; float fSpeed= 0.125f * fDeltaTime; 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 ]= -5.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_F1 ) & 1 ) != 0) { g_ShaderDebug= !g_ShaderDebug; g_bForceCompile= true; } if( ( GetAsyncKeyState( VK_F2 ) & 1 ) != 0) { g_ShaderID= (g_ShaderID + MAX_SHADER_ID - 1 ) % MAX_SHADER_ID; 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) { fCurTime= 0.0f; } if( ( GetAsyncKeyState( VK_F5 ) & 1 )!= 0) { g_fSpeedFac*= 2.0f; if( g_fSpeedFac > 32.0f ) { g_fSpeedFac= 32.0f; } } if( ( GetAsyncKeyState( VK_F6 ) & 1 ) != 0) { g_fSpeedFac/= 2.0f; if( g_fSpeedFac < 0.03125f ) { g_fSpeedFac= 0.03125f; } } 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; } } } 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; } LRESULT MessageCallback(HWND ar_Handle, UINT aw_Message, WPARAM aw_Param, LPARAM al_Param) { return DefWindowProc(ar_Handle, aw_Message, aw_Param, al_Param); } int gCurScene= 0; int gCurSceneStart= 0; int g_SceneLength[]= { 16, 16, 16, 16, 16, 16, 16, 32, 16, 16, 16, 16, 0x80000000 }; int g_SceneShader[]= { 0,0,0, 1,1,1, 2,2,2, 3,3,3, }; float g_SceneFactor[]= { 0, 0, 0, 0, 0, 1.0f, 0, 0, 1.0f, 0, 1.0f, 1.0f, 0, }; void _cdecl main() { //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 = 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(); filemon_struct fragmentShader = {0}; filemon_struct textureShader1 = {0}; filemon_struct textureShader2 = {0}; fragmentShader.shaderFile = "fragment.glsl"; fragmentShader.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); textureShader1.shaderFile = "tex1.glsl"; textureShader1.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); textureShader2.shaderFile = "tex2.glsl"; textureShader2.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent")); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &fragmentShader, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &textureShader1, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &textureShader2, 0, 0), THREAD_PRIORITY_BELOW_NORMAL); auto events = new HANDLE[2]; events[0] = fragmentShader.shaderCompileEvent; events[1] = textureShader1.shaderCompileEvent; events[2] = textureShader2.shaderCompileEvent; ShowWindow (hWnd , SW_NORMAL ); ::Sleep(100); LARGE_INTEGER li_OldTime = { 0 }; unsigned int fbo1 = 0, fbo2 = 0; int iStartTick= timeGetTime(); GLuint tex1, tex2; glGenTextures(1, &tex1); glGenTextures(1, &tex2); glBindTexture(GL_TEXTURE_2D, tex1); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, textureSize, textureSize, 0, GL_RGBA, GL_FLOAT, 0); glBindTexture(GL_TEXTURE_2D, tex2); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, textureSize, textureSize, 0, GL_RGBA, GL_FLOAT, 0); ((PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"))(1, &fbo1); ((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo1); ((PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"))(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0); ((PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"))(1, &fbo2); ((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo2); ((PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"))(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0); float lf_Time= 0.0f; do { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return; else { TranslateMessage(&msg); DispatchMessage(&msg); } } if (::WaitForMultipleObjects(3, events, false, 0) == WAIT_OBJECT_0 || g_bForceCompile) { ::Sleep(250); fragmentShader.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(fragmentShader.shaderFile, g_ShaderID, g_ShaderDebug)); textureShader1.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(textureShader1.shaderFile, g_ShaderID, g_ShaderDebug)); textureShader2.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(textureShader2.shaderFile, g_ShaderID, g_ShaderDebug)); glViewport(0, 0, textureSize, textureSize); ((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo1); ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(textureShader1.shaderProgram); ((PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"))(0, textureSize, textureSize, lf_Time, 0); glRects(-1, -1, 1, 1); ((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo2); ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(textureShader2.shaderProgram); ((PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"))(0, textureSize, textureSize, lf_Time, 0); ((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(textureShader2.shaderProgram, "V"), 0); ((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex1); glRects(-1, -1, 1, 1); ((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, 0); glViewport(0, 0, gi_ScreenWidth, gi_ScreenHeight); PrintErrors(); g_bForceCompile= false; } int SceneEnd= g_SceneLength[ gCurScene ] * (44100 * 60 / 145);//samples per tick LARGE_INTEGER li_CurrentTime, li_CurrentFrequency; QueryPerformanceCounter(&li_CurrentTime); QueryPerformanceFrequency(&li_CurrentFrequency); float lf_DiffTime = (float)(li_CurrentTime.QuadPart - li_OldTime.QuadPart) / (float)li_CurrentFrequency.QuadPart; char windowText[255]; sprintf_s( windowText, "Shader: %d Scene: %d FPS: %.2f, Render time: %.4fms", g_ShaderID, g_SceneID, 1.0f / lf_DiffTime, lf_DiffTime ); ::SetWindowTextA(hWnd, windowText); li_OldTime = li_CurrentTime; lf_Time+= lf_DiffTime / 8.0f / g_fSpeedFac; if( lf_Time > 1.0f ) { lf_Time= 0.0f; } float fBeat = lf_Time * 16.0f; while( fBeat > 1.0f ) { fBeat-= 1.0f; } if( fBeat < 0.0f) { fBeat = 0.0f; } fBeat = pow( 10.0f, 4.0f * -fBeat ); glColor3f((float)g_SceneID + lf_Time, fBeat, fBeat); MoveCam(lf_Time, lf_DiffTime); 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); ((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(fragmentShader.shaderProgram); ((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex1); ((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tex2); ((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(fragmentShader.shaderProgram, "V"), 0); ((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(fragmentShader.shaderProgram, "HEIGHT"), 1); glRects(-1, -1, 1, 1); SwapBuffers(hDC); } while ( !GetAsyncKeyState(VK_ESCAPE) ); ExitProcess(0); }