//Windows code to move 2D text around the screen #include // Header File For Windows #include // Header File For Windows Math Library #include // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #include // Header File For The GLaux Library static HGLRC hRC; // Permanent Rendering Context static HDC hDC; // Private GDI Device Context GLuint base; // Base Display List For The Font Set GLfloat cnt1; // 1st Counter Used To Move Text & For Coloring GLfloat cnt2; // 2nd Counter Used To Move Text & For Coloring BOOL keys[256]; // Array Used For The Keyboard Routine GLvoid BuildFont(GLvoid) // Build Our Bitmap Font { HFONT font; // Windows Font ID base = glGenLists(96); // Storage For 96 Characters font = CreateFont( -24, // Height Of Font 0, // Width Of Font 0, // Angle Of Escapement 0, // Orientation Angle FW_BOLD, // Font Weight FALSE, // Italic FALSE, // Underline FALSE, // Strikeout ANSI_CHARSET, // Character Set Identifier OUT_TT_PRECIS, // Output Precision CLIP_DEFAULT_PRECIS, // Clipping Precision ANTIALIASED_QUALITY, // Output Quality FF_DONTCARE|VARIABLE_PITCH, // Family And Pitch "Courier New"); // Font Name SelectObject(hDC, font); // Selects The Font We Want wglUseFontBitmaps(hDC, 32, 96, base); // Builds 96 Characters Starting At Character 32 } GLvoid KillFont(GLvoid) // Delete The Font { glDeleteLists(base, 96); // Delete All 96 Characters } GLvoid glPrint(char *text) // Custom GL "Print" Routine { if (text == NULL) // If There's No Text return; // Do Nothing glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits glListBase(base - 32); // Sets The Base Character to 32 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text glPopAttrib(); // Pops The Display List Bits } GLvoid InitGL(GLsizei Width, GLsizei Height) // Will Be Called Right After The GL Window Is Created { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Clear The Background Color To Black glClearDepth(1.0); // Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS); // The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST); // Enables Depth Testing glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix BuildFont(); // Build The Font } GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height) // Handles Window Resizing { if (Height==0) // Is Window Too Small (Divide By Zero Error) Height=1; // If So Make It One Pixel Tall // Reset The Current Viewport And Perspective Transformation glViewport(0, 0, Width, Height); glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix } GLvoid DrawGLScene(GLvoid) // Handles Rendering { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View glTranslatef(0.0f,0.0f,-1.0f); // Move One Unit Into The Screen // Pulsing Colors Based On Text Position glColor4f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)),1.0f); // Position The Text On The Screen glRasterPos3f(-0.2f+0.35f*float(cos(cnt1)), 0.35f*float(sin(cnt2)), float(cos(cnt1+cnt2))); glPrint("Hello World!"); // Print GL Text To The Screen cnt1+=0.01f; // Increase The First Counter cnt2+=0.0081f; // Increase The Second Counter } LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT Screen; // Used Later On To Get The Size Of The Window GLuint PixelFormat; // Pixel Format Storage static PIXELFORMATDESCRIPTOR pfd= // Pixel Format Descriptor { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number (?) PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 16, // Select A 16Bit Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored (?) 0, // No Alpha Buffer 0, // Shift Bit Ignored (?) 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored (?) 16, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer (?) PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved (?) 0, 0, 0 // Layer Masks Ignored (?) }; switch (message) // Tells Windows We Want To Check The Message { case WM_CREATE: // Window Creation hDC = GetDC(hWnd); // Gets A Device Context For The Window PixelFormat = ChoosePixelFormat(hDC, &pfd); // Finds The Closest Match To The Pixel Format We Set Above if (!PixelFormat) // No Matching Pixel Format? { MessageBox(0,"Can't Find A Suitable PixelFormat.","Error",MB_OK|MB_ICONERROR); PostQuitMessage(0); // This Sends A 'Message' Telling The Program To Quit break; // Prevents The Rest Of The Code From Running } if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Can We Set The Pixel Mode? { MessageBox(0,"Can't Set The PixelFormat.","Error",MB_OK|MB_ICONERROR); PostQuitMessage(0); // This Sends A 'Message' Telling The Program To Quit break; // Prevents The Rest Of The Code From Running } hRC = wglCreateContext(hDC); // Grab A Rendering Context if(!hRC) // Did We Get One? { MessageBox(0,"Can't Create A GL Rendering Context.","Error",MB_OK|MB_ICONERROR); PostQuitMessage(0); // This Sends A 'Message' Telling The Program To Quit break; // Prevents The Rest Of The Code From Running } if(!wglMakeCurrent(hDC, hRC)) // Can We Make The RC Active? { MessageBox(0,"Can't Activate GLRC.","Error",MB_OK|MB_ICONERROR); PostQuitMessage(0); // This Sends A 'Message' Telling The Program To Quit break; // Prevents The Rest Of The Code From Running } GetClientRect(hWnd, &Screen); // Grab Screen Info For The Current Window InitGL(Screen.right, Screen.bottom); // Initialize The GL Screen Using Screen Info break; case WM_DESTROY: // Windows Being Destroyed case WM_CLOSE: // Windows Being Closed ChangeDisplaySettings(NULL, 0); // Disable Fullscreen Mode KillFont(); // Deletes The Font Display List wglMakeCurrent(hDC,NULL); // Make The DC Current wglDeleteContext(hRC); // Kill The RC ReleaseDC(hWnd,hDC); // Free The DC PostQuitMessage(0); // Quit The Program break; case WM_KEYDOWN: // Key Being Held Down keys[wParam] = TRUE; // Make That Keys Cell True break; case WM_KEYUP: // Key Is Released keys[wParam] = FALSE; // Make That Keys Cell False break; case WM_SIZE: // Resizing The Screen ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // Resize To The New Window Size break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); // Pass Windows Messages } return (0); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; // Windows Message Structure WNDCLASS wc; // Windows Class Structure Used To Set Up The Type Of Window HWND hWnd; // Storage For Window Handle wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL WinClass"; if(!RegisterClass(&wc)) { MessageBox(0,"Failed To Register The Window Class.","Error",MB_OK|MB_ICONERROR); return FALSE; } hWnd = CreateWindow( "OpenGL WinClass", "Presentation by Ryan Lamb", // Title Appearing At The Top Of The Window WS_POPUP | // Popup Window WS_CLIPCHILDREN | // Clip Child Windows WS_CLIPSIBLINGS, // Clip Sibling Windows 0, 0, // The Position Of The Window On The Screen 640, 480, // The Width And Height Of The WIndow NULL, NULL, hInstance, NULL); if(!hWnd) // Was Window Created? { MessageBox(0,"Window Creation Error.","Error",MB_OK|MB_ICONERROR); return FALSE; } DEVMODE dmScreenSettings; // Developer Mode memset(&dmScreenSettings, 0, sizeof(DEVMODE)); // Clear Room To Store Settings dmScreenSettings.dmSize = sizeof(DEVMODE); // Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = 640; // Screen Width dmScreenSettings.dmPelsHeight = 480; // Screen Height dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; // Pixel Mode ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); // Switch To Full Screen ShowWindow(hWnd, SW_SHOW); // Show Our Window UpdateWindow(hWnd); // Update The Window SetFocus(hWnd); // Set Focus On The Window wglMakeCurrent(hDC,hRC); // Make DC/RC Current while (1) // Endless Loop { // Process All Messages while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { return TRUE; } } DrawGLScene(); // Draw The Scene SwapBuffers(hDC); // Swap Screen Buffers if (keys[VK_ESCAPE]) SendMessage(hWnd,WM_CLOSE,0,0); // If ESC Is Pressed Quit } }