Lesson 1 Nehe

#include <gl/opengl.h>

HGLRC       hRc = NULL;             // opengl 着色描述表
HDC         hDc = NULL;             // Windows 设备描述表
/*
    opengl 中将着色描述表与设备描述相与联接,设备描述表与GDI相互联接,从而绘图。总体顺序:
    hRc -> hDc -> GDI
*/
HWND        hWnd = NULL;
HINSTANCE   hInstance = NULL;
BOOL keys[256];
BOOL active = TRUE;                 // 当激活状态为假是时,暂停程序操做
BOOL fullscreen = TRUE;

LRESULT CALLBACK WindowProc( HWND, UINT, WPARAM, LPARAM);

GLvoid ReSizeGLScene(GLsizei width, GLsizei height){
    if (height == 0) height = 1;
    glViewport(0,0,width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // 设置视口大小
    gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int InitGL(GLvoid){
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // 开启深度测试类型
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return TRUE;
}

BOOL DrawGLScene(GLvoid){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    return TRUE;
}

GLvoid KillGLWindow(GLvoid){
    if (fullscreen){
        ChangeDisplaySettings(NULL, 0);
        ShowCursor(TRUE);
    }

    if (hRc){
        // 个人感觉此函数为 HRC 与HDC 建产相互联系的函数
        if (!wglMakeCurrent(NULL, NULL)){
            MessageBox(NULL, "释放DC或RC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
        }
        if (!wglDeleteContext(hRc)){
            MessageBox(NULL, "释放RC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
        }
        hRc = NULL;
    }
    if (hDc && !ReleaseDC(hWnd, hDc)){
        MessageBox(NULL, "释放DC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
        hDc = NULL;
    }

    if (hWnd && !DestroyWindow(hWnd)){
        MessageBox(NULL, "释放窗口句柄失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
        hWnd = NULL;
    }
    if (!UnregisterClass("opengl", hInstance)){
        MessageBox(NULL, "不能注销窗口类。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
        hInstance = NULL;
    }
}

BOOL CreateGLWindow(char* title, int width, int height, int bits, BOOL fullscreenflag){
    GLuint PixelFormat;         // 保存查找匹配的结果
    WNDCLASS wc;
    DWORD dwExStyle;            // 扩展窗口风格
    DWORD dwStyle;              // 窗口风格

    // windows 的窗口
    RECT WindowRect;
    WindowRect.left = static_cast<long>(0);
    WindowRect.right = static_cast<long>(width);
    WindowRect.top = static_cast<long>(0);
    WindowRect.bottom = static_cast<long>(height);

    // 全屏标志
    fullscreen = fullscreenflag;

    // 窗口类的定义
    hInstance       = GetModuleHandle(NULL);
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc      = WindowProc;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = 0;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground    = NULL;
    wc.lpszMenuName     = NULL;
    wc.lpszClassName    = "opengl";

    // 注册窗口类
    if (!RegisterClass(&wc)){
        MessageBox(NULL, "注册窗口失败", "错误", MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    // 全屏模式判断,操做
    if (fullscreen){
        DEVMODE dmScreenSetting;
        memset(&dmScreenSetting, 0, sizeof(dmScreenSetting));
        dmScreenSetting.dmSize          = sizeof(dmScreenSetting);
        dmScreenSetting.dmPelsHeight    = height;
        dmScreenSetting.dmPelsWidth     = width;
        dmScreenSetting.dmBitsPerPel    = bits;
        dmScreenSetting.dmFields        = DM_BITSPERPEL|DM_PELSHEIGHT|DM_PELSWIDTH;

        // 设置显示模式
        if (ChangeDisplaySettings(&dmScreenSetting, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){
            if (MessageBox(NULL, "全屏模式在当前显卡上设置失败!
使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION) == IDYES){
                fullscreen = FALSE;
            }
            else{
                MessageBox(NULL, "程序将被关闭", "错误", MB_OK|MB_ICONSTOP);
                return FALSE;
            }
        }
    }

    // 出错后进行的相应操作
    if (fullscreen){
        // WS_EX_APPWINDOW 
        // Forces a top-level window onto the taskbar when the window is visible.
        dwExStyle = WS_EX_APPWINDOW;
        dwStyle = WS_POPUP;
        ShowCursor(FALSE);
    }
    else{
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle = WS_OVERLAPPEDWINDOW;
    }
    AdjustWindowRectEx(&WindowRect,dwStyle,FALSE, dwExStyle);

    if (! (hWnd = CreateWindowEx(dwExStyle, 
                        "opengl", 
                        title,
                        WS_CLIPSIBLINGS|
                        WS_CLIPCHILDREN|
                        dwStyle, 
                        0, 0,
                        WindowRect.right-WindowRect.left, 
                        WindowRect.bottom-WindowRect.top, 
                        NULL, 
                        NULL, 
                        hInstance,
                        NULL))){
            KillGLWindow();
            MessageBox(NULL, "不能创建一个窗口设备描述表", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
    }

    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW |                // 支持窗口
        PFD_SUPPORT_OPENGL|                 // 支持 opengl
        PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        bits,
        0, 0, 0, 0, 0, 0,               // 忽略的色彩位
        0,                              // 无Alpha缓存
        0,                              // 忽略Shift Bit
        0,                              // 无累加缓存
        0, 0, 0, 0,                         // 忽略聚集位
        16,                             // 16位 Z-缓存 (深度缓存)
        0,                              // 无蒙板缓存
        0,                              // 无辅助缓存
        PFD_MAIN_PLANE,                         // 主绘图层
        0,                              // Reserved
        0, 0, 0                             // 忽略层遮罩
    };

    if (!(hDc = GetDC(hWnd))){
        KillGLWindow();
        MessageBox(NULL, "不能创建一种相匹配的像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (!(PixelFormat = ChoosePixelFormat(hDc, &pfd))){
        KillGLWindow();
        MessageBox(hWnd, "不能设置像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (!SetPixelFormat(hDc, PixelFormat, &pfd)){
        KillGLWindow();
        MessageBox(hWnd, "不能设置像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (!(hRc = wglCreateContext(hDc))){
        KillGLWindow();
        MessageBox(NULL, "不能创建openGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (!(wglMakeCurrent(hDc, hRc))){
        KillGLWindow();
        MessageBox(NULL, "不能激活当前的openGL渲染描述表", "错误", MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    ShowWindow(hWnd, SW_SHOW);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);
    ReSizeGLScene(width, height);

    if (!InitGL()){
        KillGLWindow();
        MessageBox(NULL, "Initialization Failed.","error",MB_OK|MB_ICONEXCLAMATION );
        return FALSE;
    }
    return TRUE;
}


LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch(uMsg){
    case WM_ACTIVATE: 
        {
            if (!HIWORD(wParam))
                active = TRUE;
            else
                active = FALSE;
            return 0;
        }
    case WM_SYSCOMMAND:
        {
            switch(wParam){
            case SC_SCREENSAVE:
                // 屏保运行代码
            case SC_MONITORPOWER:
                // 进入节电模式运行代码
                return 0;
            }
            break;
        }
    case WM_CLOSE:
        {
            PostQuitMessage(0);
            return 0;
        }
    case WM_KEYUP:
        {
            keys[wParam] = TRUE;
            return 0;
        }
    case WM_KEYDOWN:
        {
            keys[wParam] = FALSE;
            return 0;
        }
    case WM_SIZE:
        {
            ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
            return 0;
        }
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
    MSG msg;
    BOOL done=FALSE;

    // 提示用户选择运行模式
    if (MessageBox(NULL, "你想在全屏模式下运行吗?", "设置全屏模式", MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
        fullscreen = FALSE;

    if (!CreateGLWindow("Nehe's openGL 程序框架", 640, 480, 16, fullscreen))
        return 0;

    while (!done){
        if (PeekMessage(&msg, NULL, 0,0,PM_REMOVE)){
            if (msg.message == WM_QUIT){
                done = TRUE;
            }
            else{
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else{                               // 当没有消息时,进行的操做
            if (active){
                if (keys[VK_ESCAPE]){
                    done = TRUE;
                }
                else{
                    DrawGLScene();
                    SwapBuffers(hDc);               
                }
                if (keys[VK_F1]){
                    keys[VK_F1] =FALSE;
                    KillGLWindow();
                    fullscreen = !fullscreen;

                    // 重建opengl窗口
                    if (!CreateGLWindow("Nehe's openGL 程序框架", 640, 480, 16, fullscreen))
                    return 0;
                }
            }
        } // end if 
        } //end while 
    KillGLWindow();
    return (msg.wParam);
}// end WinMain

这里写图片描述

原文地址:https://www.cnblogs.com/laohaozi/p/12538355.html