// greensquare.cpp is an open-source example screensaver by Rachel Grey, lemming@alum.mit.edu. // Paste into an IDE to compile if desired. // I haven't chosen to include the resource file, so you'd need to provide a description string /and so forth. #include #include #include #include #include "resource.h" // get rid of these warnings: truncation from const double to float conversion from double to float // #pragma warning(disable: 4305 4244) //Define a Windows timer #define TIMER 1 #define FPS 60 // globals for size of screen static int Width, Height; static bool bTumble = true; // a global to keep track of the square's spinning static GLfloat spin = 0; ///////////////////////////////////////////////// //// INFRASTRUCTURE ENDS, SPECIFICS BEGIN /// //// /// //// In a more complex scr, I'd put all /// //// the following into other files. /// ///////////////////////////////////////////////// // Initialize OpenGL static void InitGL(HWND hWnd, HDC &hDC, HGLRC &hRC) { PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof pfd); pfd.nSize = sizeof pfd; pfd.nVersion = 1; //pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; //blaine's pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; hDC = GetDC(hWnd); int i = ChoosePixelFormat(hDC, &pfd); SetPixelFormat(hDC, i, &pfd); hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); } // Shut down OpenGL static void CloseGL(HWND hWnd, HDC hDC, HGLRC hRC) { wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); ReleaseDC(hWnd, hDC); } void SetupAnimation(int Width, int Height) { //window resizing stuff glViewport(0, 0, (GLsizei) Width, (GLsizei) Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (0) { glOrtho(-300, 300, -240, 240, 25, 75); } else { float w = 300; float h = ((w * 2) * Height / Width) / 2; glOrtho(-w, w, -h, h, 25, 75); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //camera xyz, the xyz to look at, and the up vector (+y is up) //background glClearColor(0.0, 0.0, 0.0, 0.0); //0.0s is black glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // glShadeModel(GL_FLAT); glShadeModel(GL_SMOOTH); } void OnTimer(HDC hDC) //increment and display { float xvals[] = {-30.0, -30.0, 30.0, 30.0}; float yvals[] = {-30.0, 30.0, 30.0, -30.0}; spin = spin + 1; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0.0, 0.0, 1.0); glTranslatef(120, 0, 0); glRotatef(spin * ((bTumble) ? -4.0 : -1.0), 0.0, 0.0, 1.0); //draw the square (rotated to be a diamond) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(0.1, 1.0, 0.3); // set green color glBegin(GL_POLYGON); for (int i = 0; i < 4; i++) glVertex2f(xvals[i], yvals[i]); glEnd(); glPopMatrix(); glFlush(); SwapBuffers(hDC); } void CleanupAnimation() { // didn't create any objects, so no need to clean them up } ///////// REGISTRY ACCESS FUNCTIONS /////////// void GetConfig() { if (0) { // get configuration from registry HKEY key; //DWORD lpdw; if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GreenSquare", //lpctstr 0, //reserved KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { DWORD dsize = sizeof(bTumble); DWORD dwtype = 0; RegQueryValueEx(key, "Tumble", NULL, &dwtype, (BYTE*)&bTumble, &dsize); //Finished with key RegCloseKey(key); } else //key isn't there yet--set defaults { bTumble = true; } } else { bTumble = true; } } void WriteConfig(HWND hDlg) { if (0) { HKEY key; DWORD lpdw; const char* null_str = ""; LPSTR str = const_cast(null_str); if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\GreenSquare", // lpctstr 0, // reserved str, // ptr to null-term string specifying the object type of this key REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, &lpdw) == ERROR_SUCCESS) { RegSetValueEx(key, "Tumble", 0, REG_DWORD, (BYTE*)&bTumble, sizeof(bTumble)); //Finished with keys RegCloseKey(key); } } } ////////////////////////////////////////////////// //// INFRASTRUCTURE -- THE THREE FUNCTIONS /// ////////////////////////////////////////////////// // Screen Saver Procedure LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hDC; static HGLRC hRC; static RECT rect; switch (message) { case WM_CREATE: // get window dimensions GetClientRect(hWnd, &rect); Width = rect.right; Height = rect.bottom; // get configuration from registry GetConfig(); // setup OpenGL, then animation InitGL(hWnd, hDC, hRC); SetupAnimation(Width, Height); // set timer to tick every 10 ms SetTimer(hWnd, TIMER, (int)(1000 / FPS), NULL); return 0; case WM_TIMER: OnTimer(hDC); // animate! return 0; case WM_DESTROY: KillTimer(hWnd, TIMER); CleanupAnimation(); CloseGL(hWnd, hDC, hRC); return 0; } return DefScreenSaverProc(hWnd, message, wParam, lParam); } BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { //InitCommonControls(); //would need this for slider bars or other common controls HWND aCheck; switch (message) { case WM_INITDIALOG: LoadString(hMainInstance, IDS_DESCRIPTION, szAppName, 40); GetConfig(); aCheck = GetDlgItem(hDlg, IDC_TUMBLE); SendMessage(aCheck, BM_SETCHECK, (bTumble) ? BST_CHECKED : BST_UNCHECKED, 0); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_TUMBLE: bTumble = (IsDlgButtonChecked(hDlg, IDC_TUMBLE) == BST_CHECKED); return TRUE; //cases for other controls would go here case IDOK: WriteConfig(hDlg); // get info from controls EndDialog(hDlg, LOWORD(wParam) == IDOK); return TRUE; case IDCANCEL: EndDialog(hDlg, LOWORD(wParam) == IDOK); return TRUE; } return FALSE; } //end command switch return FALSE; } // needed for SCRNSAVE.LIB BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }