//   A Simple OpenGL program for Windows Win32 API
//   Draws a rectangle in different shades of red

// Must add OPENGL32.LIB & GLU32.LIB to linker's 'Object/library 
// modules' --- 'Project'|'Settings'|'Link tab'

#include <windows.h>   // standard Windows headers
#include <GL/gl.h>     // OpenGL interface
#include <GL/glu.h>    // OpenGL utility Library interface

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawOpenGLScene(void);
HGLRC SetUpOpenGL(HWND hWnd);

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
{
    static char szClassName[] = "Myclass";
    static char szTitle[]="A Simple Win32 API OpenGL Program";
    WNDCLASS wc; 
    MSG      msg;  
    HWND     hWnd;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szClassName;
    if (!RegisterClass (&wc))
        return 0;
 
    hWnd = CreateWindow(szClassName, szTitle, 
                        WS_OVERLAPPEDWINDOW |
                            // NEED THESE for OpenGL calls to work!
                WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                                10, 10, 310, 310,
                NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow( hWnd );
    while (GetMessage(&msg, NULL, 0, 0)) 
        {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
        }

    return(msg.wParam); 
}

 
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg,
                     WPARAM wParam, LPARAM lParam )
{
    HDC hDC;
    static HGLRC hRC; // Note this is STATIC!
    PAINTSTRUCT ps;
            
    switch (msg)
        {
       case WM_CREATE:
            // Select a pixel format and create a rendering context
            hRC = SetUpOpenGL(hWnd);
            break;

        case WM_PAINT:
            // Draw the scene
            // Get a DC, make RC current & associate it with this DC
            hDC = BeginPaint(hWnd, &ps);
            wglMakeCurrent(hDC, hRC);
            DrawOpenGLScene();  // Draw the rectangles
            // We're done with the RC, so deselect it
            wglMakeCurrent(NULL, NULL);
            EndPaint(hWnd, &ps);
            break;       
            
        case WM_DESTROY:
            // Clean up and terminate
            wglDeleteContext(hRC);
            PostQuitMessage(0);
            break;

                default:
                        return DefWindowProc(hWnd, msg, wParam, lParam);
        }

        return (0);
}

//*******************************************************
//  SetUpOpenGL sets the pixel format and a rendering
//  context then returns the RC
//*******************************************************
HGLRC SetUpOpenGL(HWND hWnd)
{
    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof (PIXELFORMATDESCRIPTOR), // strcut size 
        1,                              // Version number
        PFD_DRAW_TO_WINDOW |    // Flags, draw to a window,
            PFD_SUPPORT_OPENGL, // use OpenGL
        PFD_TYPE_RGBA,          // RGBA pixel values
        24,                     // 24-bit color
        0, 0, 0,                // RGB bits & shift sizes.
        0, 0, 0,                // Don't care about them
        0, 0,                   // No alpha buffer info
        0, 0, 0, 0, 0,          // No accumulation buffer
        32,                     // 32-bit depth buffer
        0,                      // No stencil buffer
        0,                      // No auxiliary buffers
        PFD_MAIN_PLANE,         // Layer type
        0,                      // Reserved (must be 0)
        0,                      // No layer mask
        0,                      // No visible mask
        0                       // No damage mask
    };

    int nMyPixelFormatID;
    HDC hDC;
    HGLRC hRC;

    hDC = GetDC(hWnd);
    nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, nMyPixelFormatID, &pfd);
    hRC = wglCreateContext(hDC);
    ReleaseDC(hWnd, hDC);
    return hRC;
}

//******************************************************** 
//  DrawOpenGLScene uses OpenGL commands to draw the scene
//  This is where we put the OpenGL drawing commands
//********************************************************

void DrawOpenGLScene()
{
        float i;

        // Draw a rectangle in different shades of red
        for (i=0.2f; i<=1.0; i+=0.2f)
        {
                glColor3f(i, 0.0, 0.0);  // drawing color
                glBegin(GL_POLYGON);     // define the rectangle
                        glVertex2f(-0.5,-0.5);
                        glVertex2f(-0.5,0.5);
                        glVertex2f(0.5,0.5);
                        glVertex2f(0.5,-0.5);
                glEnd();
                glFlush();   // force execution
                Sleep(1000); // wait a while
        }

}